Wie kann ich überprüfen, ob der Benutzer die Berechtigung zur Verwendung der Kamera erteilt hat?


81

Der Versuch, dies zu schreiben:

if usergavepermissiontousercamera  
  opencamera
else 
  showmycustompermissionview

Es konnte kein aktueller Weg gefunden werden, um diese einfache Aufgabe zu erledigen.
Hinweis: Sollte auch mit iOS7 funktionieren, auch wenn eine andere Methode erforderlich ist


Sie sollten diesen Link überprüfen. stackoverflow.com/questions/25803217/… Sollte nicht zu schwer sein, in Swift zu übersetzen.
Mehdi.Sqalli

AVCaptureDevice und AVAuthorizationStatus werden beide von xcode nicht erkannt, vielleicht ein Fehler oder so, aber ja, das macht es ziemlich schwierig.
Esqarrouth

überprüfte diese Antwort. Es ist für die
Kamerarolle

Antworten:


176

Sie können den folgenden Code verwenden, um dasselbe zu tun:

if AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) ==  AVAuthorizationStatus.Authorized {
    // Already Authorized
} else {
    AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted: Bool) -> Void in
       if granted == true {
           // User granted
       } else {
           // User rejected
       }
   })
}

HINWEIS:

  1. Stellen Sie sicher, dass Sie das AVFoundationFramework im Abschnitt Link Binary der Erstellungsphasen hinzufügen
  2. Sie sollten import AVFoundationzum Importieren in Ihre Klasse schreibenAVFoundation

SWIFT 3

if AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) ==  AVAuthorizationStatus.authorized {
   // Already Authorized
} else {
   AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (granted: Bool) -> Void in
      if granted == true {
         // User granted
      } else {
         // User Rejected
      }
   })
}

Swift 4

if AVCaptureDevice.authorizationStatus(for: .video) ==  .authorized {
    //already authorized
} else {
    AVCaptureDevice.requestAccess(for: .video, completionHandler: { (granted: Bool) in
        if granted {
            //access allowed
        } else {
            //access denied
        }
    })
}

Vielen Dank. Das Importieren funktionierte ohne Hinzufügen zur Link-Binärdatei. Aber ich habe Foundation in den Frameworks. ist das verwandt?
Esqarrouth

1
@Esq: Sie müssen keine Binärdatei verknüpfen, da laut Swift Imports jedes Objective-C-Framework (oder jede C-Bibliothek), auf das als Modul zugegriffen werden kann, direkt in Swift importiert werden kann. Dies umfasst alle Objective-C-Systemframeworks wie Foundation, UIKit und SpriteKit sowie die mit dem System gelieferten allgemeinen C-Bibliotheken. Frohe Weihnachten ...
Midhun MP

danke, frohe weihnachten auch dir :) übrigens in ios7 wird diese methode bereits autorisiert eingegeben, obwohl sie nie die anfrage bekommen hat. Warum ist das so und wie kann ich das beheben?
Esqarrouth

@Esq: Wenn Ihre App bereits die Berechtigung hatte und in der Einstellungs-App festgelegt wurde, wird sie nicht erneut gefragt. Überprüfen Sie Ihre Einstellungs-App, ob Sie die Berechtigung haben oder nicht.
Midhun MP

Ich habe die Simulatoreinstellungen zurückgesetzt, bevor ich dies versuche. ging und überprüfte die Einstellungen nichts über die App ist da drin. versuchen es auf ios7.1 Simulator
Esqarrouth

18

Swift 3.0 aktualisierte Lösung

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: alertPromptToAllowCameraAccessViaSetting()
    case .notDetermined: alertToEncourageCameraAccessInitially()
    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)
}

Ich denke, Sie mischten Namen von Methoden alertToEncourageCameraAccessInitially und alertPromptToAllowCameraAccessViaSetting;)
jonaszmclaren

Sie können die Antwort verbessern. Es wird besser sein. Andernfalls, wenn ich frei sein werde, werde ich es überprüfen. Danke :) @jonaszmclaren
Sourabh Sharma

12

Das Folgende ist eine bereinigte Antwort, die für Swift 4.x aktualisiert wurde:

Ab iOS 10 müssen Sie auch die Berechtigung in der Datei info.plist anfordern, um einen Absturz zu vermeiden:

Geben Sie hier die Bildbeschreibung ein

Datenschutz - Beschreibung der Kameranutzung

Sie müssen eine Zeichenfolge angeben, die dem Benutzer mit diesem Schlüssel angezeigt wird. Andernfalls stürzt der Versuch ab, auf die Kamera zuzugreifen.

import AVFoundation

func checkCameraAccess() {
    switch AVCaptureDevice.authorizationStatus(for: .video) {
    case .denied:
        print("Denied, request permission from settings")
        presentCameraSettings()
    case .restricted:
        print("Restricted, device owner must approve")
    case .authorized:
        print("Authorized, proceed")
    case .notDetermined:
        AVCaptureDevice.requestAccess(for: .video) { success in
            if success {
                print("Permission granted, proceed")
            } else {
                print("Permission denied")
            }
        }
    }
}

func presentCameraSettings() {
    let alertController = UIAlertController(title: "Error",
                                  message: "Camera access is denied",
                                  preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "Cancel", style: .default))
    alertController.addAction(UIAlertAction(title: "Settings", style: .cancel) { _ in
        if let url = URL(string: UIApplicationOpenSettingsURLString) {
            UIApplication.shared.open(url, options: [:], completionHandler: { _ in
                // Handle
            })
        }
    })

    present(alertController, animated: true)
}

Dadurch werden die vier möglichen Antworten geprüft und dann entweder um Erlaubnis gebeten, falls dies der Fall ist notDetermined, oder der Benutzer wird zu den Einstellungen weitergeleitet, um sie zu aktivieren, falls dies der Fall ist denied. Wenn dies restrictedder Fall ist , kann der aktuelle Benutzer es möglicherweise nicht aktivieren, Sie sollten ihm jedoch eine Anleitung geben.


9

Dadurch wird die Kamera geöffnet, wenn der Benutzer die Erlaubnis dazu erteilt. Andernfalls wird eine Warnung angezeigt, wenn Sie um Erlaubnis gebeten werden.

func openCamera(){
        
        let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
        
        switch (authStatus){
            
        case .notDetermined, .restricted, .denied:
            showAlert(title: "Unable to access the Camera", message: "To enable access, go to Settings > Privacy > Camera and turn on Camera access for this app.")
        case .authorized:
            alert.dismiss(animated: true, completion: nil)
            if(UIImagePickerController .isSourceTypeAvailable(.camera)){
                picker.sourceType = .camera
                picker.showsCameraControls=true
                picker.allowsEditing=true
                self.viewController!.present(picker, animated: true, completion: nil)
            }
        }
}

Rufen Sie danach diese Funktion auf, um eine Warnung anzuzeigen

func showAlert(title:String, message:String) {
        let alert = UIAlertController(title: title,
                                      message: message,
                                      preferredStyle: UIAlertController.Style.alert)
        
        let okAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
        alert.addAction(okAction)
        
        let settingsAction = UIAlertAction(title: "Settings", style: .default, handler: { _ in
            // Take the user to Settings app to possibly change permission.
            guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
            if UIApplication.shared.canOpenURL(settingsUrl) {
                if #available(iOS 10.0, *) {
                    UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                        // Finished opening URL
                    })
                } else {
                    // Fallback on earlier versions
                    UIApplication.shared.openURL(settingsUrl)
                }
            }
        })
        alert.addAction(settingsAction)
        
        self.viewController!.present(alert, animated: true, completion: nil)
    }

+1, da es nach einer kleinen Änderung bei mir funktioniert hat. Alles gut, bis auf den ersten Fall .notDetermined ist wahr, also können wir entweder das tun, was wir in einem autorisierten Fall getan haben, weil es um Zulassen / Verweigern bittet, oder wir können dem Benutzer "AVCaptureDevice.requestAccess (for : .Video)". Ab dem nächsten Versuch folgt der Schalterfall basierend auf der ersten Antwort. Auch bis zum ersten Mal, wenn wir dies ablehnen / zulassen, wird dies in den Datenschutzeinstellungen nicht angezeigt.
Lokesh Purohit

2

Ich habe die obige Antwort geändert und die anfängliche Eingabeaufforderung entfernt, da das System, wenn wir die Kamera des Geräts verwenden möchten, selbst zur Eingabe von Berechtigungen auffordert:

func checkPermissions() {
    let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)

    switch authStatus {
    case .authorized:
        setupCamera()
    case .denied:
        alertPromptToAllowCameraAccessViaSetting()
    default:
        // Not determined fill fall here - after first use, when is't neither authorized, nor denied
        // we try to use camera, because system will ask itself for camera permissions
        setupCamera()
    }
}

func alertPromptToAllowCameraAccessViaSetting() {
    let alert = UIAlertController(title: "Error", message: "Camera access required to...", preferredStyle: UIAlertControllerStyle.alert)

    alert.addAction(UIAlertAction(title: "Cancel", style: .default))
    alert.addAction(UIAlertAction(title: "Settings", style: .cancel) { (alert) -> Void in
        UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
    })

    present(alert, animated: true)
}

2

Sie können das AVFoundation-Framework importieren und die unten gezeigte Methode authorizationStatus (for :) verwenden und die entsprechenden Fälle behandeln.

switch AVCaptureDevice.authorizationStatus(for: .video) {
    case .authorized: // The user has previously granted access to the camera.
        self.setupCaptureSession()

    case .notDetermined: // The user has not yet been asked for camera access.
        AVCaptureDevice.requestAccess(for: .video) { granted in
            if granted {
                self.setupCaptureSession()
            }
        }

    case .denied: // The user has previously denied access.
        return
    case .restricted: // The user can't grant access due to restrictions.
        return
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.