在iOS 8中显示相机权限对话框

在iOS 8中显示相机权限对话框,ios,permissions,camera,ios8,ios-permissions,Ios,Permissions,Camera,Ios8,Ios Permissions,当我的应用程序首次尝试在iOS 8上访问摄像头时,用户会看到一个摄像头权限对话框,与iOS 7中用于麦克风访问的麦克风对话框非常相似 在iOS 7中,可以事先调用麦克风权限对话框,查看是否授予了权限(例如,请参阅)。在iOS 8中,是否有类似的方法来调用摄影机权限对话框?是否可以将该对话框合并为麦克风和摄像头访问权限?我遇到了类似的问题,如果用户在第一次收到提示时拒绝摄像头访问,则在摄像头模式下按下按钮拍摄快照会导致黑屏 但是我想检测用户拒绝访问并提示他们必须打开,但我找不到任何功能来检查当前用

当我的应用程序首次尝试在iOS 8上访问摄像头时,用户会看到一个摄像头权限对话框,与iOS 7中用于麦克风访问的麦克风对话框非常相似


在iOS 7中,可以事先调用麦克风权限对话框,查看是否授予了权限(例如,请参阅)。在iOS 8中,是否有类似的方法来调用摄影机权限对话框?是否可以将该对话框合并为麦克风和摄像头访问权限?

我遇到了类似的问题,如果用户在第一次收到提示时拒绝摄像头访问,则在摄像头模式下按下按钮拍摄快照会导致黑屏

但是我想检测用户拒绝访问并提示他们必须打开,但我找不到任何功能来检查当前用户的摄像头访问,是否有这样的功能

编辑:以下检查将让您在IOS 8中了解摄像头访问:

#import <AVFoundation/AVFoundation.h>

AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
    if(status == AVAuthorizationStatusAuthorized) { // authorized
        
    }
    else if(status == AVAuthorizationStatusDenied){ // denied
        
    }
    else if(status == AVAuthorizationStatusRestricted){ // restricted
        
        
    }
    else if(status == AVAuthorizationStatusNotDetermined){ // not determined
        
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if(granted){ // Access has been granted ..do something
               
            } else { // Access denied ..do something
               
            }
        }];
    }

#导入):

以下是我们最终使用的方法:

if ([AVCaptureDevice respondsToSelector:@selector(requestAccessForMediaType: completionHandler:)]) {
    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
        // Will get here on both iOS 7 & 8 even though camera permissions weren't required 
        // until iOS 8. So for iOS 7 permission will always be granted.
        if (granted) {
            // Permission has been granted. Use dispatch_async for any UI updating
            // code because this block may be executed in a thread.
            dispatch_async(dispatch_get_main_queue(), ^{
                [self doStuff];
            });                
        } else {
            // Permission has been denied.
        }
    }];
} else {
    // We are on iOS <= 6. Just do what we need to do.
    [self doStuff];
}
if([AVCaptureDevice respondsToSelector:@selector(requestAccessForMediaType:completionHandler:)){
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL已授予){
//将在iOS 7和iOS 8上访问此页面,即使不需要摄像头权限
//直到iOS 8。因此,对于iOS 7,将始终授予权限。
如果(授予){
//已授予权限。请使用dispatch\u async进行任何UI更新
//代码,因为此块可以在线程中执行。
dispatch\u async(dispatch\u get\u main\u queue()^{
[自我调节];
});                
}否则{
//许可被拒绝了。
}
}];
}否则{

//我们在iOS上对于我来说,在iOS7和iOS8上的这项工作:

    ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];

    switch (status) {
        case ALAuthorizationStatusAuthorized:
            break;

        case ALAuthorizationStatusRestricted:
        case ALAuthorizationStatusDenied:
            break;

        case ALAuthorizationStatusNotDetermined:
            break;
    }
这是我的Swift解决方案(iOS 8),我需要相机进行QR扫描,所以我必须提示它的使用

这提供了

  • 鼓励用户在默认允许摄像头访问问题之前选择允许if

  • 如果用户拒绝了第一个请求,可以轻松访问设置

  • 要使其运行,请调用check camera in ViewDidDisplay/或ViewDidLoad等。我需要使用ViewDidDisplay,以便设置自定义相机视图约束

    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)
    }
    
    感谢上面jamix提供的使用dispatch_async的技巧,使显示新设置的摄像头功能的响应速度更快


    很抱歉混合使用了尾随闭包..想尝试一下。

    所有答案似乎都无法同时检查麦克风和摄像头权限。我们的代码针对授予摄像头权限但拒绝麦克风访问的情况进行检查

    因为我们是Swift新手,所以如果
    语句是最优的,那么嵌套粗糙的闭包和
    语句就不太可能了。请分享改进代码的建议!但至少到目前为止,它在测试中是有效的

        AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in
            if (videoGranted) {
                AVCaptureDevice.requestAccessForMediaType(AVMediaTypeAudio, completionHandler: { (audioGranted: Bool) -> Void in
                    if (audioGranted) {
                        dispatch_async(dispatch_get_main_queue()) {
                            // Both video & audio granted
                        }
                    } else {
                        // Rejected audio
                    }
                })
            } else {
                // Rejected video
            }
        })
    

    我对应用程序代理进行访问检查

    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)
                    })
                }
            }
    

    *

    我的问题是,由于最近的一些构建配置更改,
    捆绑包名称和
    捆绑包显示名称未在我的Info.plist中设置。这是一种不太可能的情况……但我花了几个小时才搞定。希望这对其他人有所帮助。

    对于Swift 3,您可以将其添加到您的
    vi中EWillappear
    第一个视图控制器的方法:

    首先导入
    AVFoundation
    框架

    import AVFoundation
    
    然后:

    别忘了在您的
    Info.plist上添加
    隐私-摄像头使用说明
    • Swift 3.0解决方案

      进口AVF基金会

    注意:在Info.plist上添加隐私-摄像头使用说明码

    //马克:摄像机操作

            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)
            }
    

    一个小注释-requestAccessForMediaType方法也出现在iOS 7中(当时iOS仅在某些地区要求获得摄像头权限)。因此else部分适用于取消按钮设置
    样式:.Default
    ,为另一个按钮设置
    样式:.Cancel
    ?这只是一个错误,还是你这样做是有目的的?我想我只是想让一个比另一个更突出,仅此而已。就像粗体和普通字体一样。@DogCoffee我对permission pro有点困惑mpt用于最初访问摄像头。这不是iOS内置的开发人员无法模仿的东西吗?我们只能检查之前是否被拒绝,然后在设置中提示更新??我前一段时间做了这个,应用程序需要摄像头用于我的QR阅读器。iOS问到摄像头是否可以使用。我只是想让用户知道为什么。Mos当一些事情突然出现,要求这个或那个我知道我自己的时候,我通常会先拒绝。这只是我说的方式-漂亮,请接受。@DogCoffee,所以我不需要为首次访问权限提示创建函数,我可以让iOS在后台这样做,我只需要满足他们在后台拒绝权限的情况过去?它就像一个符咒。别忘了导入:
    #import
    在IOS 9中不再工作,因为AlassetLibrary已被弃用。只有解决视频和音频权限的答案。旁注,你不能这样做对我来说太疯狂了
            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)
            }