Skip to content

Commit aba5bd0

Browse files
author
Emilio Pavia
committed
Fix camera permission handling
1 parent 0262a02 commit aba5bd0

5 files changed

+59
-47
lines changed

ScienceJournal/CaptureSession/CameraAccessHandler.swift

+12-8
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,27 @@ import AVFoundation
1919
/// Handles checking and asking for camera access permission.
2020
classCameraAccessHandler{
2121

22+
/// Returns `true` if the user authorized access to the device camera.
23+
staticvarhasGrantedAccess:Bool{
24+
AVCaptureDevice.authorizationStatus(for:.video)==.authorized
25+
}
26+
2227
/// Checks the permissions status of the camera, and requests access if needed.
2328
///
2429
/// - Parameter requestCompletion: Called with the status of the permission (true if granted),
25-
/// when access had to be requested.
26-
/// - Returns: Whether or not permission has been granted.
27-
staticfunc checkForPermission(requestCompletion:((Bool)->Void)?=nil)->Bool{
30+
staticfunc checkForPermission(requestCompletion:((Bool)->Void)?=nil){
2831
letauthStatus=AVCaptureDevice.authorizationStatus(for:.video)
2932
switch authStatus {
30-
case.denied,.restricted:returnfalse
31-
case.authorized:returntrue
33+
case.denied,.restricted:requestCompletion?(false)
34+
case.authorized:requestCompletion?(true)
3235
case.notDetermined:
3336
// Prompt user for the permission to use the camera.
3437
AVCaptureDevice.requestAccess(for:.video){ granted in
35-
requestCompletion?(granted)
38+
DispatchQueue.main.async{
39+
requestCompletion?(granted)
40+
}
3641
}
37-
returnfalse
38-
@unknowndefault:returnfalse
42+
@unknowndefault:requestCompletion?(false)
3943
}
4044
}
4145

ScienceJournal/CaptureSession/CaptureSessionInterruptionObserver.swift

+11-15
Original file line numberDiff line numberDiff line change
@@ -46,30 +46,26 @@ class CaptureSessionInterruptionObserver {
4646
/// recording, during which the camera cannot be used.
4747
varisCameraUseAllowed:Bool{
4848
return !isCaptureSessionInterrupted && !isBrightnessSensorInUse &&
49-
CameraAccessHandler.checkForPermission()
49+
CameraAccessHandler.hasGrantedAccess
5050
}
5151

52-
varcameraAvailability:CameraAvailability{
53-
54-
if isBrightnessSensorInUse {
55-
return.blockedByBrightnessSensor
52+
// MARK: - Public
53+
func checkCameraAvailability(handler:@escaping(CameraAvailability)->Void){
54+
guard !isBrightnessSensorInUse else{
55+
handler(.blockedByBrightnessSensor)
56+
return
5657
}
5758

58-
if isCaptureSessionInterrupted {
59-
return.captureInterrupted
59+
guard !isCaptureSessionInterrupted else{
60+
handler(.captureInterrupted)
61+
return
6062
}
6163

62-
// Note: this check will request perms if they are not determined,
63-
// so it's not a 1:1 match with permissions denied
64-
ifCameraAccessHandler.checkForPermission(){
65-
return.available
66-
}else{
67-
return.permissionsDenied
64+
CameraAccessHandler.checkForPermission{
65+
$0 ?handler(.available):handler(.permissionsDenied)
6866
}
6967
}
7068

71-
// MARK: - Public
72-
7369
// MARK: - Private
7470

7571
/// Use `shared`.

ScienceJournal/UI/ExperimentCoordinatorViewController.swift

+15-11
Original file line numberDiff line numberDiff line change
@@ -1752,17 +1752,21 @@ class ExperimentCoordinatorViewController: MaterialHeaderViewController, DrawerP
17521752
}
17531753

17541754
func cameraButtonPressed(){
1755-
switchCaptureSessionInterruptionObserver.shared.cameraAvailability {
1756-
case.permissionsDenied:
1757-
showCameraPermissionsDeniedAlert()
1758-
case.blockedByBrightnessSensor:
1759-
showSnackbar(withMessage:String.inputCameraBlockedByBrightnessSensor,
1760-
category:nil,
1761-
actionTitle:String.actionOk,
1762-
actionHandler:nil
1763-
)
1764-
default: // Handles .available and .captureInterrupted
1765-
present(cameraImageProvider.cameraViewController, animated:true)
1755+
CaptureSessionInterruptionObserver.shared.checkCameraAvailability{[weak self]in
1756+
guardlet self =selfelse{return}
1757+
1758+
switch $0 {
1759+
case.permissionsDenied:
1760+
self.showCameraPermissionsDeniedAlert()
1761+
case.blockedByBrightnessSensor:
1762+
showSnackbar(withMessage:String.inputCameraBlockedByBrightnessSensor,
1763+
category:nil,
1764+
actionTitle:String.actionOk,
1765+
actionHandler:nil
1766+
)
1767+
default: // Handles .available and .captureInterrupted
1768+
self.present(self.cameraImageProvider.cameraViewController, animated:true)
1769+
}
17661770
}
17671771
}
17681772

ScienceJournal/UI/PhotoCapturer.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,14 @@ class PhotoCapturer: NSObject, AVCapturePhotoCaptureDelegate {
9999

100100
/// The permissions state of the capturer.
101101
varisCameraPermissionGranted:Bool{
102-
letgranted=CameraAccessHandler.checkForPermission{(permission)in
102+
ifCameraAccessHandler.hasGrantedAccess {
103+
returntrue
104+
}
105+
106+
CameraAccessHandler.checkForPermission{(permission)in
103107
self.delegate?.photoCapturerCameraPermissionsDidChange(accessGranted: permission)
104108
}
105-
returngranted
109+
returnfalse
106110
}
107111

108112
/// Switches to a camera.

ScienceJournal/UI/TrialDetailViewController.swift

+15-11
Original file line numberDiff line numberDiff line change
@@ -1763,17 +1763,21 @@ class TrialDetailViewController: MaterialHeaderViewController,
17631763
}
17641764

17651765
func cameraButtonPressed(){
1766-
switchCaptureSessionInterruptionObserver.shared.cameraAvailability {
1767-
case.permissionsDenied:
1768-
showCameraPermissionsDeniedAlert()
1769-
case.blockedByBrightnessSensor:
1770-
showSnackbar(withMessage:String.inputCameraBlockedByBrightnessSensor,
1771-
category:nil,
1772-
actionTitle:String.actionOk,
1773-
actionHandler:nil
1774-
)
1775-
default: // Handles .available and .captureInterrupted
1776-
present(cameraImageProvider.cameraViewController, animated:true)
1766+
CaptureSessionInterruptionObserver.shared.checkCameraAvailability{[weak self]in
1767+
guardlet self =selfelse{return}
1768+
1769+
switch $0 {
1770+
case.permissionsDenied:
1771+
self.showCameraPermissionsDeniedAlert()
1772+
case.blockedByBrightnessSensor:
1773+
showSnackbar(withMessage:String.inputCameraBlockedByBrightnessSensor,
1774+
category:nil,
1775+
actionTitle:String.actionOk,
1776+
actionHandler:nil
1777+
)
1778+
default: // Handles .available and .captureInterrupted
1779+
self.present(self.cameraImageProvider.cameraViewController, animated:true)
1780+
}
17771781
}
17781782
}
17791783

0 commit comments

Comments
 (0)
close