Представление диалога разрешения камеры в iOS 8
когда мое приложение пытается получить доступ к камере в первый раз на iOS 8, пользователю предоставляется диалоговое окно разрешения камеры, похожее на микрофон для доступа к микрофону в iOS 7.
в iOS 7 можно было заранее вызвать диалоговое окно разрешения микрофона и посмотреть, было ли предоставлено разрешение (см. этот вопрос, например). Есть ли аналогичный способ вызвать диалоговое окно разрешения камеры в iOS 8? Можно ли объединить диалог для микрофона и разрешение на доступ к камере?
9 ответов:
вот подход, который мы в конечном итоге использовали:
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]; }
я сталкиваюсь с аналогичной проблемой, если пользователь отказал в доступе к камере, когда они впервые запрашиваются, нажав кнопку, чтобы сделать снимок, приводит к черному экрану в режиме камеры.
однако я хочу обнаружить, что пользователь отказался от доступа и запрашивать их, он должен быть включен, но я не могу найти никаких функций для проверки текущего доступа к камере пользователя, есть ли такая функция?
EDIT: следующая проверка позволит вам узнать в 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 } }]; }эта информация была найдена по следующему вопросу (как узнать, что приложение имеет доступ к камере или не программно в iOS8):
вот мое быстрое решение (iOS 8), мне нужна была камера для QR-сканирования, поэтому действительно нужно было подсказать ее использование.
Это обеспечивает
предложите пользователю выбрать разрешить, если перед вопросом разрешить доступ к камере по умолчанию
простой способ доступа к настройкам, если пользователь отклонил первый запрос.
чтобы заставить его работать call check camera в ViewDidAppear / или ViewDidLoad и т. д. Я необходимо использовать viewDidAppear, чтобы мои пользовательские ограничения просмотра камеры были настроены.
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, маловероятно, что узловатые вложенные замыкания и
ifзаявления являются оптимальными. Пожалуйста, поделитесь предложениями по улучшению кода! Но по крайней мере это работает до сих пор в тестировании.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 } })
Swift 3.0 Решение
импорт AVFoundation
Примечание: добавить конфиденциальность-ключ описания использования камеры на вашей информации.файл 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) }
для меня это работа на iOS7 и iOS8:
ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus]; switch (status) { case ALAuthorizationStatusAuthorized: break; case ALAuthorizationStatusRestricted: case ALAuthorizationStatusDenied: break; case ALAuthorizationStatusNotDetermined: break; }
для Swift 3, Вы можете добавить это на свой
viewWillAppearметод вашего первого контроллера вида:сначала импортировать
AVFoundationрамкиimport AVFoundationзатем:
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") } }не забудьте добавить
Privacy - Camera Usage DescriptionнаInfo.plist
Я делаю проверку доступа к делегату приложения.
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) }) } }*
проблема для меня была в том, что
Bundle nameиBundle Display Nameне были установлены в моем Инфо.файл plist в связи с некоторыми последними построения изменения конфигурации. Вроде маловероятный случай... Но мне потребовалось несколько часов, чтобы разобраться с этим. Надеюсь, это поможет кому-то еще.
Comments