Обнаружение разрешения камеры в iOS
Я разрабатываю очень простое видео приложение. Я использую официальный контроль: UIImagePickerController.
6 ответов:
Регистрация
AVAuthorizationStatus
и обрабатывать случаи должным образом.NSString *mediaType = AVMediaTypeVideo; AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType]; if(authStatus == AVAuthorizationStatusAuthorized) { // do your logic } else if(authStatus == AVAuthorizationStatusDenied){ // denied } else if(authStatus == AVAuthorizationStatusRestricted){ // restricted, normally won't happen } else if(authStatus == AVAuthorizationStatusNotDetermined){ // not determined?! [AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) { if(granted){ NSLog(@"Granted access to %@", mediaType); } else { NSLog(@"Not granted access to %@", mediaType); } }]; } else { // impossible, unknown authorization status }
начиная с iOS 10 необходимо указать
NSCameraUsageDescription
введите свою информацию.plist, чтобы иметь возможность запросить доступ к камере, в противном случае ваше приложение будет сбой во время выполнения. Смотрите API, Требующие Описания Использования.
обязательно:
import AVFoundation
The Свифт код ниже проверяет все возможные разрешения гласит:
Swift 4
let cameraMediaType = AVMediaType.video let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: cameraMediaType) switch cameraAuthorizationStatus { case .denied: break case .authorized: break case .restricted: break case .notDetermined: // Prompting user for the permission to use the camera. AVCaptureDevice.requestAccess(for: cameraMediaType) { granted in if granted { print("Granted access to \(cameraMediaType)") } else { print("Denied access to \(cameraMediaType)") } } }
Swift 3
let cameraMediaType = AVMediaTypeVideo let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: cameraMediaType) switch cameraAuthorizationStatus { case .denied: break case .authorized: break case .restricted: break case .notDetermined: // Prompting user for the permission to use the camera. AVCaptureDevice.requestAccess(forMediaType: cameraMediaType) { granted in if granted { print("Granted access to \(cameraMediaType)") } else { print("Denied access to \(cameraMediaType)") } } }
Swift 2.2
let cameraMediaType = AVMediaTypeVideo let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatusForMediaType(cameraMediaType) switch cameraAuthorizationStatus { case .Denied: break case .Authorized: break case .Restricted: break case .NotDetermined: // Prompting user for the permission to use the camera. AVCaptureDevice.requestAccessForMediaType(cameraMediaType) { granted in if granted { print("Granted access to \(cameraMediaType)") } else { print("Denied access to \(cameraMediaType)") } } }
как интересная заметка, знаете ли вы, что iOS убивает приложение, если оно работает, пока вы меняете свои разрешения камеры в настройках?
С форума разработчиков Apple:
система фактически убивает ваше приложение, если пользователь переключает ваше приложение доступ к камера в настройках. То же самое относится к любой защищенной dataclass в разделе Настройки→Конфиденциальность.
extension AVCaptureDevice { enum AuthorizationStatus { case justDenied case alreadyDenied case restricted case justAuthorized case alreadyAuthorized } class func authorizeVideo(completion: ((AuthorizationStatus) -> Void)?) { AVCaptureDevice.authorize(mediaType: AVMediaTypeVideo, completion: completion) } class func authorizeAudio(completion: ((AuthorizationStatus) -> Void)?) { AVCaptureDevice.authorize(mediaType: AVMediaTypeAudio, completion: completion) } private class func authorize(mediaType: String, completion: ((AuthorizationStatus) -> Void)?) { let status = AVCaptureDevice.authorizationStatus(forMediaType: mediaType) switch status { case .authorized: completion?(.alreadyAuthorized) case .denied: completion?(.alreadyDenied) case .restricted: completion?(.restricted) case .notDetermined: AVCaptureDevice.requestAccess(forMediaType: mediaType, completionHandler: { (granted) in if(granted) { completion?(.justAuthorized) } else { completion?(.justDenied) } }) } } }
и тогда для того, чтобы использовать его вы
AVCaptureDevice.authorizeVideo(completion: { (status) in //Your work here })
в качестве дополнения к ответу от @Raptor следует упомянуть следующее. Вы можете получить следующую ошибку, начиная с iOS 10:
This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
чтобы исправить это, убедитесь, что вы обрабатываете результаты из основного потока следующим образом (Swift 3):
private func showCameraPermissionPopup() { let cameraMediaType = AVMediaTypeVideo let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: cameraMediaType) switch cameraAuthorizationStatus { case .denied: NSLog("cameraAuthorizationStatus=denied") break case .authorized: NSLog("cameraAuthorizationStatus=authorized") break case .restricted: NSLog("cameraAuthorizationStatus=restricted") break case .notDetermined: NSLog("cameraAuthorizationStatus=notDetermined") // Prompting user for the permission to use the camera. AVCaptureDevice.requestAccess(forMediaType: cameraMediaType) { granted in DispatchQueue.main.sync { if granted { // do something } else { // do something else } } } } }
укажите ключ NSCameraUsageDescription в Info.plist в первую очередь. Затем проверьте AVAuthorizationStatus если разрешено, то представьте UIImagePickerController. Это сработает.
Swift: Использование AVFoundation
- добавить AVFoundation к цели - > построить фазы - > связать двоичный файл с библиотеками.
- импорт AVFoundation на ViewController.
- On Info.plist, добавить следующее:
- На Контроллере Вид:
@IBAction func cameraButtonClicked (отправитель: AnyObject) {
let authorizationStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) print(authorizationStatus.rawValue) if AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) == AVAuthorizationStatus.Authorized{ self.openCameraAfterAccessGrantedByUser() } else { print("No Access") dispatch_async(dispatch_get_main_queue()) { [unowned self] in AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted :Bool) -> Void in if granted == true { // User granted self.openCameraAfterAccessGrantedByUser() } else { // User Rejected alertToEncourageCameraAccessWhenApplicationStarts() } }); } } //Open camera func openCameraAfterAccessGrantedByUser() { if(UIImagePickerController .isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)){ self.cameraAndGalleryPicker!.sourceType = UIImagePickerControllerSourceType.Camera cameraAndGalleryPicker?.delegate = self cameraAndGalleryPicker?.allowsEditing = false cameraAndGalleryPicker!.cameraCaptureMode = .Photo cameraAndGalleryPicker!.modalPresentationStyle = .FullScreen presentViewController(self.cameraAndGalleryPicker!, animated: true, completion: nil) } else { } } //Show Camera Unavailable Alert func alertToEncourageCameraAccessWhenApplicationStarts() { //Camera not available - Alert let cameraUnavailableAlertController = UIAlertController (title: "Camera Unavailable", message: "Please check to see if it is disconnected or in use by another application", preferredStyle: .Alert) let settingsAction = UIAlertAction(title: "Settings", style: .Destructive) { (_) -> Void in let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString) if let url = settingsUrl { dispatch_async(dispatch_get_main_queue()) { UIApplication.sharedApplication().openURL(url) } } } let cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil) cameraUnavailableAlertController .addAction(settingsAction) cameraUnavailableAlertController .addAction(cancelAction) self.window?.rootViewController!.presentViewController(cameraUnavailableAlertController , animated: true, completion: nil) }