Wykrywanie uprawnień kamery w systemie iOS
Rozwijam bardzo prostą aplikację wideo. Używam oficjalnej kontroli: UIImagePickerController.
Oto problem. Podczas prezentacji interfejsu UIImagePickerController po raz pierwszy, iOS poprosi o pozwolenie. Użytkownik może kliknąć TAK lub nie. Jeśli użytkownik kliknie nie, Kontrola nie zostanie odrzucona. Zamiast tego, jeśli użytkownik nadal kliknie przycisk start, liczniki włączają się, gdy ekran jest zawsze czarny, a użytkownik nie może zatrzymać liczników ani cofnąć. Jedyne co użytkownik może zrobić to zabić aplikację. Następnym razem, gdy UIImagePickerController jest przedstawiony, nadal jest czarny ekran i użytkownik nie może wrócić, jeśli kliknięcie start.
Zastanawiałem się, czy to błąd. Czy jest jakiś sposób możemy wykryć uprawnienia kamery tak, że możemy zdecydować się pokazać UIImagePickerController lub nie?
6 answers
Sprawdź AVAuthorizationStatus
i zajmij się sprawami prawidłowo.
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
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-23 17:04:04
Od iOS 10 musisz określić
NSCameraUsageDescription
klucz w informacji.plist, aby móc poprosić o dostęp do kamery, w przeciwnym razie aplikacja zawiesi się w czasie wykonywania. Zobacz API Wymagające Opisów Użycia .
Upewnij się, że:
import AVFoundation
Poniższy kod Swift sprawdza wszystkie możliwe Stany uprawnień:
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)")
}
}
}
Jako ciekawostkę, Czy wiesz, że iOS zabija aplikację, jeśli jest działa podczas zmiany uprawnień aparatu w Ustawieniach?
Z forum programistów Apple:
System faktycznie zabija aplikację, jeśli użytkownik włącza aplikację dostęp do kamery w Ustawieniach. To samo dotyczy wszelkich chronionych dataclass w sekcji Ustawienia → Prywatność.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-28 14:07:25
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)
}
})
}
}
}
A następnie, aby go użyć, robisz
AVCaptureDevice.authorizeVideo(completion: { (status) in
//Your work here
})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-06 03:33:31
Jako uzupełnienie odpowiedzi od @ Raptor należy wymienić: W systemie iOS może pojawić się następujący błąd 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.
Aby to naprawić, upewnij się, że obsługujesz wyniki z głównego wątku w następujący sposób (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
}
}
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-08 09:42:54
Określ klucz NSCameraUsageDescription w Info.plist pierwszy. Następnie sprawdź AVAuthorizationStatus jeśli jest autoryzowany, a następnie przedstaw interfejs użytkownika. To zadziała.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-27 13:29:12
Swift: Using AVFoundation
- Dodaj AVFoundation do Target - > Build Phases - > Link Binary with Libraries.
- Importuj AVFoundation w ViewController.
- Na Info.plist, dodaj:
- On View Controller:
@ IBAction func cameraButtonClicked (sender: 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)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-08 04:58:26