Dialoogvenster voor cameratoestemming presenteren in iOS 8

Wanneer mijn app voor de eerste keer toegang probeert te krijgen tot de camera op iOS 8, krijgt de gebruiker een dialoogvenster voor cameratoestemming te zien, vergelijkbaar met het microfoonvenster voor microfoontoegang in iOS 7.

In iOS 7 was het mogelijk om vooraf het microfoontoestemmingsdialoogvenster op te roepen en te zien of de toestemming was verleend (zie deze vraag, bijvoorbeeld). Is er een vergelijkbare manier om het cameratoestemmingsdialoogvenster in iOS 8 op te roepen? Kan het dialoogvenster worden gecombineerd voor toegangsrechten voor microfoon EN camera?


Antwoord 1, autoriteit 100%

Dit is de aanpak die we uiteindelijk hebben gebruikt:

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];
}

Antwoord 2, autoriteit 68%

Ik loop tegen een soortgelijk probleem aan, als de gebruiker de toegang tot de camera heeft geweigerd wanneer ze hier voor het eerst om worden gevraagd, door op de knop te drukken om snapshotresultaten te maken in een zwart scherm in de cameramodus.

Ik wil echter detecteren dat de gebruiker de toegang heeft geweigerd en hen vragen dat het moet worden ingeschakeld, maar ik kan geen functies vinden om de huidige cameratoegang van de gebruiker te controleren, is er een dergelijke functie?

EDIT: De volgende controle zal u in IOS 8 informeren over cameratoegang:

#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
            }
        }];
    }

Deze informatie is gevonden op de volgende vraag (Hoe weet u of die applicatie cameratoegang heeft of niet programmatisch in iOS8):


Antwoord 3, autoriteit 59%

Hier is mijn snelle oplossing (iOS 8), ik had de camera nodig voor het scannen van QR-codes, dus ik moest echt vragen om het te gebruiken.

Dit biedt

  1. Moedig de gebruiker aan om toestaan ​​te selecteren als voorafgaand aan de standaard vraag om cameratoegang toe te staan

  2. Eenvoudige manier om toegang te krijgen tot instellingen als de gebruiker het eerste verzoek heeft afgewezen.

Om het aan de gang te krijgen, moet u de camera controleren in ViewDidAppear / of ViewDidLoad enz. Ik moest viewDidAppear gebruiken, zodat mijn aangepaste cameraweergavebeperkingen werden ingesteld.

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

Met dank aan jamix hierboven voor de tip voor het gebruik van dispatch_async – maakt de reactie om de nieuw ingestelde camerafunctie zo veel sneller weer te geven.

Sorry voor een mix van achterblijvende sluitingen.. wilde ze uitproberen.


Antwoord 4, autoriteit 18%

Geen van de antwoorden lijkt te controleren op zowel microfoon- als camerarechten. Onze code vergelijkt het scenario waarin cameratoestemmingen worden verleend, maar microfoontoegang wordt geweigerd.

Aangezien we nieuw zijn bij Swift, is het onwaarschijnlijk dat de ingewikkeld geneste sluitingen en if-statements optimaal zijn. Deel alstublieft suggesties voor het verbeteren van de code! Maar het werkt in ieder geval tot nu toe bij het testen.

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

Antwoord 5, autoriteit 9%

  • Swift 3.0-oplossing

    AVFoundation importeren

Opmerking:voeg Privacy toe – Beschrijving cameragebruik op uw Info.plist

//MARK: camerabediening

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

Antwoord 6, autoriteit 5%

Voor Swift 3 kunt u dit toevoegen aan uw viewWillAppear-methode van uw eerste weergavecontroller:

Importeer eerst het AVFoundationframework

import AVFoundation

Dan:

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

Vergeet niet om Privacy - Camera Usage Descriptiontoe te voegen aan uw Info.plist


Antwoord 7, autoriteit 4%

Voor mij werkt dit op iOS7 en iOS8:

   ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
    switch (status) {
        case ALAuthorizationStatusAuthorized:
            break;
        case ALAuthorizationStatusRestricted:
        case ALAuthorizationStatusDenied:
            break;
        case ALAuthorizationStatusNotDetermined:
            break;
    }

Antwoord 8, autoriteit 3%

Ik voer een toegangscontrole uit bij de app-gemachtigde.

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

*


Antwoord 9, Autoriteit 2%

Het probleem voor mij was dat Bundle nameen Bundle Display Namewaren niet ingesteld in mijn info.plist vanwege een aantal recente build configuratie-veranderingen. Een soort van onwaarschijnlijke zaak … maar het kostte me een paar uur om dit naar beneden te spijkeren. Hopelijk helpt het voor iemand anders.

Other episodes