I\'d like to add flashlight functionality to my app in Swift. How can I go about doing that?
Like so:
func turnTorchOn(){
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if device.hasTorch {
device.lockForConfiguration(nil)
device.setTorchModeOnWithLevel(1.0, error: nil)
device.unlockForConfiguration()
}
}
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()
}
}
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)
}
}
}
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)
}
}
}
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.
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)")
}
}