webentwicklung-frage-antwort-db.com.de

Erkennen Sie die Erlaubnis der Kamera in iOS

Ich entwickle eine sehr einfache Video-App. Ich benutze die offizielle Steuerung: UIImagePickerController.

Hier liegt das Problem. Wenn Sie den UIImagePickerController zum ersten Mal präsentieren, werden Sie vom iOS um Erlaubnis gebeten. Der Benutzer kann auf Ja oder Nein klicken. Wenn der Benutzer auf Nein klickt, wird das Steuerelement nicht geschlossen. Wenn der Benutzer stattdessen weiter auf die Startschaltfläche klickt, werden die Zeitgeber eingeschaltet, während der Bildschirm immer schwarz ist, und der Benutzer kann die Zeitgeber nicht anhalten oder zurückkehren. Der Benutzer kann die App nur beenden. Das nächste Mal, wenn der UIImagePickerController angezeigt wird, ist der Bildschirm weiterhin schwarz und der Benutzer kann nicht zurückkehren, wenn er auf Start klickt.

Ich habe mich gefragt, ob es ein Fehler ist. Gibt es eine Möglichkeit, die Erlaubnis der Kamera zu erkennen, um zu entscheiden, ob der UIImagePickerController angezeigt werden soll oder nicht?

135
user418751

Überprüfen Sie die AVAuthorizationStatus und behandeln Sie die Fälle ordnungsgemäß.

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
}
221
Raptor

Seit iOS 10 müssen Sie in Ihrer Info.plist den NSCameraUsageDescription Schlüssel angeben, um nach dem Zugriff auf die Kamera fragen zu können. Andernfalls stürzt Ihre App zur Laufzeit ab. Siehe APIs, die Verwendungsbeschreibungen erfordern .


Stellen Sie sicher, dass:

import AVFoundation

Der folgende Swift Code prüft auf alle möglichen Berechtigungszustände:

Swift 4 und neuer

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

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

Wussten Sie, dass iOS die App beendet, wenn sie ausgeführt wird, während Sie die Kameraberechtigungen in den Einstellungen ändern?

Vom Apple Entwicklerforum:

Das System beendet Ihre App tatsächlich, wenn der Benutzer den Zugriff Ihrer App in den Einstellungen auf camera umschaltet. Gleiches gilt für alle geschützten Datenklassen im Bereich Einstellungen → Datenschutz.

76

Als Ergänzung zur Antwort von @Raptor sollte folgendes erwähnt werden. Möglicherweise wird ab iOS 10 die folgende Fehlermeldung angezeigt: 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.

Um dies zu beheben, stellen Sie sicher, dass Sie die Ergebnisse des Hauptthreads wie folgt verarbeiten (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
                }
            }
        }
    }
}
2
Bart van Kuik

Schnelle Lösung

extension AVCaptureDevice {
    enum AuthorizationStatus {
        case justDenied
        case alreadyDenied
        case restricted
        case justAuthorized
        case alreadyAuthorized
        case unknown
    }

    class func authorizeVideo(completion: ((AuthorizationStatus) -> Void)?) {
        AVCaptureDevice.authorize(mediaType: AVMediaType.video, completion: completion)
    }

    class func authorizeAudio(completion: ((AuthorizationStatus) -> Void)?) {
        AVCaptureDevice.authorize(mediaType: AVMediaType.audio, completion: completion)
    }

    private class func authorize(mediaType: AVMediaType, completion: ((AuthorizationStatus) -> Void)?) {
        let status = AVCaptureDevice.authorizationStatus(for: mediaType)
        switch status {
        case .authorized:
            completion?(.alreadyAuthorized)
        case .denied:
            completion?(.alreadyDenied)
        case .restricted:
            completion?(.restricted)
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: mediaType, completionHandler: { (granted) in
                DispatchQueue.main.async {
                    if granted {
                        completion?(.justAuthorized)
                    } else {
                        completion?(.justDenied)
                    }
                }
            })
        @unknown default:
            completion?(.unknown)
        }
    }
}

Und dann, um es zu benutzen, tust du es

AVCaptureDevice.authorizeVideo(completion: { (status) in
   //Your work here
})
2
Josh Bernfeld

Geben Sie zuerst den NSCameraUsageDescription-Schlüssel in Info.plist an. Überprüfen Sie dann AVAuthorizationStatus, falls autorisiert, und zeigen Sie dann den UIImagePickerController an. Es wird klappen.

0
Yogendra Singh