Skip to content

Commit 8217af4

Browse files
🔦 Control: Add Flashlight
- Add toggle method on/off method with default parameter
1 parent 5c262e9 commit 8217af4

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

Sources/Control/Flashlight.swift

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//
2+
// Flashlight.swift
3+
// ControlKit
4+
//
5+
6+
import AVFoundation
7+
import OSLog
8+
9+
extension Control {
10+
11+
/// 🔦 Control the device's flashlight.
12+
public enum Flashlight {}
13+
}
14+
15+
extension Control.Flashlight {
16+
17+
/// Indicates whether the device's flashlight is currently turned on.
18+
///
19+
/// - Returns: A Boolean value indicating the flashlight state. Returns `true` if the flashlight is on, otherwise `false`.
20+
public static var isOn: Bool {
21+
(deviceWithFlashlight?.torchLevel ?? 0) > 0
22+
}
23+
24+
/// Toggles the device's flashlight on/off.
25+
///
26+
/// - Parameter isOn: A Boolean value to specify the desired state of the flashlight.
27+
/// Pass `true` to turn it on or `false` to turn it off.
28+
/// If no value is provided, the flashlight toggles its current state.
29+
/// - Important: The flashlight can only be used while the app is in the foreground.
30+
/// If the flashlight is on and the app is backgrounded, the flashlight will turn off.
31+
/// - Note: If the device does not have a flashlight, this method does nothing.
32+
public static func toggle( _ isOn: Bool = !isOn) {
33+
guard let deviceWithFlashlight else {
34+
return
35+
}
36+
do {
37+
try deviceWithFlashlight.lockForConfiguration()
38+
if isOn {
39+
try deviceWithFlashlight.setTorchModeOn(level: AVCaptureDevice.maxAvailableTorchLevel)
40+
} else {
41+
deviceWithFlashlight.torchMode = .off
42+
}
43+
deviceWithFlashlight.unlockForConfiguration()
44+
} catch {
45+
log.error("Error toggling flashlight: \(error.localizedDescription) to \(isOn ? "on" : "off")")
46+
}
47+
}
48+
49+
private static var deviceWithFlashlight: AVCaptureDevice? {
50+
guard
51+
let device = AVCaptureDevice.default(for: .video),
52+
device.hasTorch
53+
else {
54+
#if targetEnvironment(simulator)
55+
log.info("Simulator does not have a flashlight (yet)")
56+
#else
57+
log.info("Flashlight (torch) not available")
58+
#endif
59+
return nil
60+
}
61+
return device
62+
}
63+
64+
private static let log = Logger(subsystem: Control.subsystem, category: "Flashlight")
65+
}

0 commit comments

Comments
 (0)