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
-
Moedig de gebruiker aan om toestaan te selecteren als voorafgaand aan de standaard vraag om cameratoegang toe te staan
-
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 AVFoundation
framework
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 Description
toe 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 name
en Bundle Display Name
waren 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.