Presenting camera permission dialog in iOS 8

后端 未结 9 1457
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-29 17:45

When my app tries to access the camera for the first time on iOS 8, the user is presented with a camera permission dialog, much like the microphone one for microphone access

相关标签:
9条回答
  • 2020-11-29 18:20

    The issue for me was that Bundle name and Bundle Display Name were not getting set in my Info.plist due to some recent build configuration changes. Kind of an unlikely case... But it took me a few hours to nail this down. Hopefully it helps for someone else.

    0 讨论(0)
  • 2020-11-29 18:23

    For Swift 3, you can add this on your viewWillAppear method of your first view controller:

    First import the AVFoundation framework

    import AVFoundation
    

    Then:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        let authorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
    
        switch authorizationStatus {
        case .notDetermined:
            AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in
                if granted {
                    print("access granted")
                }
                else {
                    print("access denied")
                }
            }
        case .authorized:
            print("Access authorized")
        case .denied, .restricted:
            print("restricted")
    
        }
    }
    

    Don't forget to add Privacy - Camera Usage Description key on your Info.plist

    0 讨论(0)
  • 2020-11-29 18:28

    For me this work on iOS7 and iOS8:

        ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
    
        switch (status) {
            case ALAuthorizationStatusAuthorized:
                break;
    
            case ALAuthorizationStatusRestricted:
            case ALAuthorizationStatusDenied:
                break;
    
            case ALAuthorizationStatusNotDetermined:
                break;
        }
    
    0 讨论(0)
  • 2020-11-29 18:30

    Here is my Swift Solution (iOS 8), I needed the camera for QR scanning so really had to prompt its use.

    This provides

    1. Encourage the user to select allow if prior to the default allow camera access question

    2. Easy way to access settings if the user denied the first request.

    To get it running call check camera in ViewDidAppear / or ViewDidLoad etc. I needed to use viewDidAppear so my custom camera views constraints were set up.

    func checkCamera() {
        let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
        switch authStatus {
        case .authorized: break // Do your stuff here i.e. allowScanning()
        case .denied: alertToEncourageCameraAccessInitially()
        case .notDetermined: alertPromptToAllowCameraAccessViaSetting()
        default: alertToEncourageCameraAccessInitially()
        }
    }
    
    func alertToEncourageCameraAccessInitially() {
        let alert = UIAlertController(
            title: "IMPORTANT",
            message: "Camera access required for QR Scanning",
            preferredStyle: UIAlertControllerStyle.alert
        )
        alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
        alert.addAction(UIAlertAction(title: "Allow Camera", style: .cancel, handler: { (alert) -> Void in
            UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
        }))
        present(alert, animated: true, completion: nil)
    }
    
    func alertPromptToAllowCameraAccessViaSetting() {
    
        let alert = UIAlertController(
            title: "IMPORTANT",
            message: "Please allow camera access for QR Scanning",
            preferredStyle: UIAlertControllerStyle.alert
        )
        alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel) { alert in
            if AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo).count > 0 {
                AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in
                    DispatchQueue.main.async() {
                        self.checkCamera() } }
            }
            }
        )
        present(alert, animated: true, completion: nil)
    }
    

    Thanks to jamix above for the tip for using dispatch_async - makes the response to show the newly set camera function so much faster.

    Sorry for a mix of trailing closures.. wanted to try them out.

    0 讨论(0)
  • 2020-11-29 18:37
    • Swift 3.0 Solution

      import AVFoundation

    Note: add Privacy - Camera Usage Description key on your Info.plist

    //MARK: Camera Handling

            func callCamera(){
                let myPickerController = UIImagePickerController()
                myPickerController.delegate = self;
                myPickerController.sourceType = UIImagePickerControllerSourceType.camera
    
                self.present(myPickerController, animated: true, completion: nil)
                NSLog("Camera");
            }
            func checkCamera() {
                let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
                switch authStatus {
                case .authorized: callCamera() // Do your stuff here i.e. callCameraMethod()
                case .denied: alertToEncourageCameraAccessInitially()
                case .notDetermined: alertPromptToAllowCameraAccessViaSetting()
                default: alertToEncourageCameraAccessInitially()
                }
            }
    
            func alertToEncourageCameraAccessInitially() {
                let alert = UIAlertController(
                    title: "IMPORTANT",
                    message: "Camera access required for capturing photos!",
                    preferredStyle: UIAlertControllerStyle.alert
                )
                alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
                alert.addAction(UIAlertAction(title: "Allow Camera", style: .cancel, handler: { (alert) -> Void in
                    UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
                }))
                present(alert, animated: true, completion: nil)
            }
    
            func alertPromptToAllowCameraAccessViaSetting() {
    
                let alert = UIAlertController(
                    title: "IMPORTANT",
                    message: "Camera access required for capturing photos!",
                    preferredStyle: UIAlertControllerStyle.alert
                )
                alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel) { alert in
                    if AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo).count > 0 {
                        AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in
                            DispatchQueue.main.async() {
                                self.checkCamera() } }
                    }
                    }
                )
                present(alert, animated: true, completion: nil)
            }
    
    0 讨论(0)
  • 2020-11-29 18:37

    I make an access check on the app delegate.

    import UIKit
    import AVFoundation
    import Photos
    
            func applicationDidBecomeActive(application: UIApplication) {
                cameraAllowsAccessToApplicationCheck()
                internetAvailabilityOnApplicationCheck()
                photoLibraryAvailabilityCheck()
            }
    
        //MARK:- CAMERA ACCESS CHECK
            func cameraAllowsAccessToApplicationCheck()
            {
                let authorizationStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
                switch authorizationStatus {
                case .NotDetermined:
                    // permission dialog not yet presented, request authorization
                    AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo,
                        completionHandler: { (granted:Bool) -> Void in
                            if granted {
                                print("access granted")
                            }
                            else {
                                print("access denied")
                            }
                    })
                case .Authorized:
                    print("Access authorized")
                case .Denied, .Restricted:
                alertToEncourageCameraAccessWhenApplicationStarts()
                default:
                    print("DO NOTHING")
                }
            }
            //MARK:- PHOTO LIBRARY ACCESS CHECK
            func photoLibraryAvailabilityCheck()
            {
                if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.Authorized
                {
    
                }
                else
                {
                    var cameraUnavailableAlertController = UIAlertController (title: "Photo Library Unavailable", message: "Please check to see if device settings doesn't allow photo library access", preferredStyle: .Alert)
    
                    var settingsAction = UIAlertAction(title: "Settings", style: .Destructive) { (_) -> Void in
                        let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString)
                        if let url = settingsUrl {
                            UIApplication.sharedApplication().openURL(url)
                        }
                    }
                    var cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil)
                    cameraUnavailableAlertController .addAction(settingsAction)
                    cameraUnavailableAlertController .addAction(cancelAction)
                    self.window?.rootViewController!.presentViewController(cameraUnavailableAlertController , animated: true, completion: nil)
                }
            }
            func internetAvailabilityOnApplicationCheck()
            {
                //MARK:- INTERNET AVAILABLITY
                if InternetReachability.isConnectedToNetwork() {
    
                }
                else
                {
                    dispatch_async(dispatch_get_main_queue(), {
    
                        //INTERNET NOT AVAILABLE ALERT
                        var internetUnavailableAlertController = UIAlertController (title: "Network Unavailable", message: "Please check your internet connection settings and turn on Network Connection", preferredStyle: .Alert)
    
                        var settingsAction = UIAlertAction(title: "Settings", style: .Destructive) { (_) -> Void in
                            let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString)
                            if let url = settingsUrl {
                                UIApplication.sharedApplication().openURL(url)
                            }
                        }
                        var cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil)
                        internetUnavailableAlertController .addAction(settingsAction)
                        internetUnavailableAlertController .addAction(cancelAction)
                        self.window?.rootViewController!.presentViewController(internetUnavailableAlertController , animated: true, completion: nil)
                    })
                }
            }
    

    *

    0 讨论(0)
提交回复
热议问题