@@ -21,22 +21,36 @@ protocol CameraPermissionProviding: ObservableObject {
2121
2222@MainActor
2323final class CameraPermissionService : ObservableObject , CameraPermissionProviding {
24-
24+
2525 // MARK: - Published Properties
26-
26+
2727 @Published private( set) var isPermissionGranted : Bool = false
28-
28+
2929 // MARK: - Private Properties
30-
30+
3131 private var isCheckingPermission = false
32-
32+
33+ // MARK: - Debug/Simulator Detection
34+
35+ private var isRunningInSimulator : Bool {
36+ #if DEBUG && targetEnvironment(simulator)
37+ return true
38+ #else
39+ return false
40+ #endif
41+ }
42+
3343 // MARK: - Initialization
34-
44+
3545 init ( ) {
46+ // Simulator always has camera permissions granted in DEBUG builds
47+ #if DEBUG && targetEnvironment(simulator)
48+ self . isPermissionGranted = true
49+ #else
3650 // Initialize with current permission state synchronously to prevent UI delays
3751 let currentStatus = AVCaptureDevice . authorizationStatus ( for: . video)
3852 self . isPermissionGranted = ( currentStatus == . authorized)
39-
53+
4054 // Set up notification observer for when the app becomes active
4155 // (in case user changed permissions in Settings)
4256 NotificationCenter . default. addObserver (
@@ -45,6 +59,7 @@ final class CameraPermissionService: ObservableObject, CameraPermissionProviding
4559 name: UIApplication . didBecomeActiveNotification,
4660 object: nil
4761 )
62+ #endif
4863 }
4964
5065 deinit {
@@ -56,39 +71,49 @@ final class CameraPermissionService: ObservableObject, CameraPermissionProviding
5671 /// Checks and updates camera permission state
5772 /// Returns true if permission is granted, false otherwise
5873 func checkAndUpdatePermissions( ) async -> Bool {
74+ #if DEBUG && targetEnvironment(simulator)
75+ // Simulator always has permissions in DEBUG builds
76+ return true
77+ #else
5978 guard !isCheckingPermission else {
6079 return isPermissionGranted
6180 }
62-
81+
6382 isCheckingPermission = true
6483 defer { isCheckingPermission = false }
65-
84+
6685 let currentStatus = AVCaptureDevice . authorizationStatus ( for: . video)
67-
86+
6887 switch currentStatus {
6988 case . authorized:
7089 updatePermissionState ( granted: true )
7190 return true
72-
91+
7392 case . notDetermined:
7493 let granted = await AVCaptureDevice . requestAccess ( for: . video)
7594 updatePermissionState ( granted: granted)
7695 return granted
77-
96+
7897 case . denied, . restricted:
7998 updatePermissionState ( granted: false )
8099 return false
81-
100+
82101 @unknown default :
83102 updatePermissionState ( granted: false )
84103 return false
85104 }
105+ #endif
86106 }
87107
88108 /// Synchronously updates the permission state based on current authorization status
89109 func updatePermissionState( ) {
110+ #if DEBUG && targetEnvironment(simulator)
111+ // Simulator always has permissions in DEBUG builds
112+ updatePermissionState ( granted: true )
113+ #else
90114 let currentStatus = AVCaptureDevice . authorizationStatus ( for: . video)
91115 updatePermissionState ( granted: currentStatus == . authorized)
116+ #endif
92117 }
93118
94119 // MARK: - Private Methods
@@ -100,10 +125,15 @@ final class CameraPermissionService: ObservableObject, CameraPermissionProviding
100125 }
101126
102127 @objc private func handleAppDidBecomeActive( ) {
128+ #if DEBUG && targetEnvironment(simulator)
129+ // Simulator always has permissions in DEBUG builds - no need to check
130+ return
131+ #else
103132 // Refresh permission state when app becomes active
104133 // (user might have changed permissions in Settings)
105134 // Skip if we're currently checking permissions to avoid race condition
106135 guard !isCheckingPermission else { return }
107136 updatePermissionState ( )
137+ #endif
108138 }
109- }
139+ }
0 commit comments