How to turn flashlight ON and OFF in swift?
Matthew Martinez
I'd like to add flashlight functionality to my app in Swift. How can I go about doing that?
014 Answers
Update #1: (torchActive isn't returning the expected value; perhaps because it's been modified)
Update #2: For Swift 2.0
To toggle the flash from on to off (not just "on" as in mad pig's answer), you can use the following method:
func toggleFlash() { let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) if (device.hasTorch) { do { try device.lockForConfiguration() if (device.torchMode == AVCaptureTorchMode.On) { device.torchMode = AVCaptureTorchMode.Off } else { do { try device.setTorchModeOnWithLevel(1.0) } catch { print(error) } } device.unlockForConfiguration() } catch { print(error) } }
}I used nested do-catch blocks to implement Awesomeness's suggestion from the comments. This way, even if try device.setTorchModeOnWithLevel(1.0) fails, the device is properly unlocked for configuration.
Update #3: For Swift 4:
(I edited the code a bit to my personal taste)
func toggleFlash() { guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return } guard device.hasTorch else { return } do { try device.lockForConfiguration() if (device.torchMode == AVCaptureDevice.TorchMode.on) { device.torchMode = AVCaptureDevice.TorchMode.off } else { do { try device.setTorchModeOn(level: 1.0) } catch { print(error) } } device.unlockForConfiguration() } catch { print(error) }
}Original answer:
To toggle the flash from on to off (not just "on" as in mad pig's answer), you can use the following method:
func toggleFlash() { let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) if (device.hasTorch) { device.lockForConfiguration(nil) let torchOn = !device.torchActive device.setTorchModeOnWithLevel(1.0, error: nil) device.torchMode = torchOn ? AVCaptureTorchMode.On : AVCaptureTorchMode.Off device.unlockForConfiguration() }
} 4 Updated Swift 4 Answer:
func toggleTorch(on: Bool) { guard let device = AVCaptureDevice.default(for: AVMediaType.video), device.hasTorch else { return } do { try device.lockForConfiguration() device.torchMode = on ? .on : .off device.unlockForConfiguration() } catch { print("Torch could not be used") }
}Then to actually turn it on or off, call the function and pass in a true or false boolean.
toggleTorch(on: true) of toggleTorch(on: false)
I got this answer from Hacking with Swift, however their example had an error in it.
They used AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) but this produces an error saying defaultDevice doesn't exist. So I changed it to AVCaptureDevice.default(for: AVMediaType.video)
I've updated @Lyndsey Scott's great answer for Swift 2.0
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) if (device.hasTorch) { do { try device.lockForConfiguration() if (device.torchMode == AVCaptureTorchMode.On) { device.torchMode = AVCaptureTorchMode.Off } else { try device.setTorchModeOnWithLevel(1.0) } device.unlockForConfiguration() } catch { print(error) } } 2 Swift 5
The solution was already written by many, but I want to propose also the more concise one I came up in my project:
func toggleTorch(on: Bool) { guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return } guard device.hasTorch else { print("Torch isn't available"); return } do { try device.lockForConfiguration() device.torchMode = on ? .on : .off // Optional thing you may want when the torch it's on, is to manipulate the level of the torch if on { try device.setTorchModeOn(level: AVCaptureDevice.maxAvailableTorchLevel.significand) } device.unlockForConfiguration() } catch { print("Torch can't be used") }
}As mentioned in the comment, you can also change the torch level when it's on, which I find quite handy.
Also import AVFoundation to use torch.
0For swift 3
func toggleFlash() { if let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo), device.hasTorch { do { try device.lockForConfiguration() let torchOn = !device.isTorchActive try device.setTorchModeOnWithLevel(1.0) device.torchMode = torchOn ? .on : .off device.unlockForConfiguration() } catch { print("error") } }
} 0 Like so:
func turnTorchOn(){ let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) if device.hasTorch { device.lockForConfiguration(nil) device.setTorchModeOnWithLevel(1.0, error: nil) device.unlockForConfiguration() }
} For xcode 9.1, swift 4 (updated to not crash if no torch):
func toggleFlash() { let device = AVCaptureDevice.default(for: AVMediaType.video) if (device != nil) { if (device!.hasTorch) { do { try device!.lockForConfiguration() if (device!.torchMode == AVCaptureDevice.TorchMode.on) { device!.torchMode = AVCaptureDevice.TorchMode.off } else { do { try device!.setTorchModeOn(level: 1.0) } catch { print(error) } } device!.unlockForConfiguration() } catch { print(error) } } }
} Solution For Swift 4 With Condition torch is available or not
func flashlight() { guard let device = AVCaptureDevice.default(for: AVMediaType.video) else{ return } if (device.hasTorch) { do { try device.lockForConfiguration() if (device.torchMode == .on) { device.torchMode = .off } else { device.torchMode = .on } device.unlockForConfiguration() } catch { print("Torch could not be used") print(error) } } else{ print("Torch is not available") } }The Solution is Combination of @Joshua Dance And @Lance
Swift 4.2
if let device = AVCaptureDevice.default(for: AVMediaType.video) { if (device.hasTorch) { do { try device.lockForConfiguration() let torchOn = !device.isTorchActive try device.setTorchModeOn(level: 1.0) device.torchMode = torchOn ? AVCaptureDevice.TorchMode.on : AVCaptureDevice.TorchMode.off device.unlockForConfiguration() } catch { print(error.localizedDescription) } }
} SwiftUI
// TorchState.swift
import SwiftUI
import AVFoundation
class TorchState: ObservableObject { @Published var isOn: Bool = false { didSet { toggleTorch(isOn) } } private func toggleTorch(_ isOn: Bool) { guard let device = AVCaptureDevice.default(for: .video), device.hasTorch else { return } do { try device.lockForConfiguration() device.torchMode = isOn ? .on : .off if isOn { try device.setTorchModeOn(level: AVCaptureDevice.maxAvailableTorchLevel) } device.unlockForConfiguration() } catch { print("Error: \(error)") } }
}Example (iOS 14.0):
//ContentView.swift
import SwiftUI
struct ContentView: View { @StateObject var torchState = TorchState() var body: some View { Toggle(isOn: $torchState.isOn) { Text("Torch") } }
} 1 Refactored. Swift 5.4
import AVFoundation
extension UIDevice { static func toggleFlashLight() { guard let device = AVCaptureDevice.default(for: AVMediaType.video), device.hasTorch else { return } do { try device.lockForConfiguration() try device.setTorchModeOn(level: 1.0) device.torchMode = device.isTorchActive ? .off : .on device.unlockForConfiguration() } catch { assert(false, "error: device flash light, \(error)") } }
} If you want to use only one button to on or off flashlight this is code;
func toggleTorch() { guard let device = AVCaptureDevice.default(for: AVMediaType.video), device.hasTorch else { return } do { try device.lockForConfiguration() if device.torchMode == AVCaptureDevice.TorchMode.on { device.torchMode = .off } else { device.torchMode = .on } device.unlockForConfiguration() } catch { print("Torch could not be used") } }you can call toggleTorch() in button click function to on and off flashlight.
Swift version 5.2.4
func toggleFlash(on: Bool ) { guard let device = AVCaptureDevice.default(for: .video), device.hasTorch else { return } do { try device.lockForConfiguration() device.torchMode = on ? .on : .off if on { try device.setTorchModeOn(level: AVCaptureDevice.maxAvailableTorchLevel) } device.unlockForConfiguration() } catch { print("Error: \(error)") } } Swift 4.1
@objc func Flash() { let device = AVCaptureDevice.default(for: AVMediaType.video) if (device?.hasTorch)! { do { try device?.lockForConfiguration() if (device?.torchMode == AVCaptureDevice.TorchMode.on) { device?.torchMode = AVCaptureDevice.TorchMode.off } else { do { try device?.setTorchModeOn(level: 1.0) } catch { print(error) } } device?.unlockForConfiguration() } catch { print(error) } } } 0