restricciones - ¿Hay alguna manera de pedirle al usuario acceso a la cámara después de que ya lo haya denegado en iOS?
olvide mi codigo de restricciones iphone 5 (4)
Código completo de acceso a la cámara y acceso a la biblioteca de fotos
import AVFoundation
Para manejar la acción de la cámara, use el siguiente código: Llamada de método
func openCameraOrLibrary(){
let imagePicker = UIImagePickerController()
let alertController : UIAlertController = UIAlertController(title: "Select Camera or Photo Library".localized, message: "", preferredStyle: .actionSheet)
let cameraAction : UIAlertAction = UIAlertAction(title: "Camera".localized, style: .default, handler: {(cameraAction) in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) == true {
if self.isCamAccessDenied() == false { **//Calling cam access method here**
imagePicker.sourceType = .camera
imagePicker.delegate = self
self.present(imagePicker, animated: true, completion: nil)
}
}else{
self.present(self.showAlert(Title: "", Message: "Camera is not available on this Device or accesibility has been revoked!".localized), animated: true, completion: nil)
self.showTabbar()
}
})
let libraryAction : UIAlertAction = UIAlertAction(title: "Photo Library", style: .default, handler: {(libraryAction) in
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) == true {
imagePicker.sourceType = .photoLibrary
imagePicker.delegate = self
self.present(imagePicker, animated: true, completion: nil)
}else{
self.showTabbar()
self.present(self.showAlert(Title: "", Message: "Photo Library is not available on this Device or accesibility has been revoked!".localized), animated: true, completion: nil)
}
})
let cancelAction : UIAlertAction = UIAlertAction(title: "Cancel".localized, style: .cancel , handler: {(cancelActn) in
self.showTabbar()
})
alertController.addAction(cameraAction)
alertController.addAction(libraryAction)
alertController.addAction(cancelAction)
alertController.popoverPresentationController?.sourceView = view
alertController.popoverPresentationController?.sourceRect = view.frame
self.present(alertController, animated: true, completion: nil)
self.hideTabbar()
}
Método para manejar la funcionalidad de acceso a la cámara
func isCamAccessDenied()-> Bool
{
let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
if status == .restricted || status == .denied {
DispatchQueue.main.async
{
var alertText = "It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:/n/n1. Close this app./n/n2. Open the Settings app./n/n3. Scroll to the bottom and select this app in the list./n/n4. Turn the Camera on./n/n5. Open this app and try again."
var alertButton = "OK"
var goAction = UIAlertAction(title: alertButton, style: .default, handler: nil)
if UIApplication.shared.canOpenURL(URL(string: UIApplicationOpenSettingsURLString)!)
{
alertText = "It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:/n/n1. Touch the Go button below to open the Settings app./n/n2. Turn the Camera on./n/n3. Open this app and try again."
alertButton = "OK"
goAction = UIAlertAction(title: alertButton, style: .default, handler: {(alert: UIAlertAction!) -> Void in
UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: nil)
})
}
let alert = UIAlertController(title: "Error", message: alertText, preferredStyle: .alert)
alert.addAction(goAction)
self.present(alert, animated: true, completion: nil)
}
return true
}
return false
}
Estoy usando este código, pero desafortunadamente no funciona.
Después de que un usuario haya denegado el acceso a la cámara, quiero pedirle permiso para volver a usar la cámara la próxima vez que intente cargarla (en este caso, es un escáner de código de barras que usa la vista de la cámara).
Siempre obtengo
AVAuthorizationStatusDenied
y luego
granted
siempre devuelve
NO
automáticamente aunque lo solicite nuevamente en el código.
Muchos de mis usuarios me envían un correo electrónico diciéndome "mi pantalla está negra cuando intento escanear el código de barras" y es porque han negado el acceso a la cámara por alguna razón. Quiero poder incitarlos nuevamente porque lo más probable es que la negación haya sido un error.
¿Hay alguna forma posible de hacer esto?
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(authStatus == AVAuthorizationStatusAuthorized)
{
NSLog(@"%@", @"You have camera access");
}
else if(authStatus == AVAuthorizationStatusDenied)
{
NSLog(@"%@", @"Denied camera access");
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if(granted){
NSLog(@"Granted access to %@", AVMediaTypeVideo);
} else {
NSLog(@"Not granted access to %@", AVMediaTypeVideo);
}
}];
}
else if(authStatus == AVAuthorizationStatusRestricted)
{
NSLog(@"%@", @"Restricted, normally won''t happen");
}
else if(authStatus == AVAuthorizationStatusNotDetermined)
{
NSLog(@"%@", @"Camera access not determined. Ask for permission.");
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if(granted){
NSLog(@"Granted access to %@", AVMediaTypeVideo);
} else {
NSLog(@"Not granted access to %@", AVMediaTypeVideo);
}
}];
}
else
{
NSLog(@"%@", @"Camera access unknown error.");
}
Después de investigar un poco, parece que no puedes hacer lo que me gustaría. Aquí está la alternativa que codifiqué para abrir un cuadro de diálogo y abrir la aplicación Configuración automáticamente si está en iOS 8+.
Algunas notas:
-
Desde iOS 10, debe especificar la clave
NSCameraUsageDescription
en su Info.plist para poder solicitar acceso a la cámara; de lo contrario, su aplicación se bloqueará en el tiempo de ejecución. - Una vez que el usuario cambie los permisos de su aplicación, la matará. Maneje en consecuencia y guarde los datos necesarios antes de que el usuario presione el botón "Ir".
- En algún momento entre iOS 8 y 11, Apple ya no requería que el usuario tocara la celda de Privacidad en las aplicaciones de Configuración para acceder y cambiar la configuración de la Cámara. Es posible que desee cambiar sus instrucciones sobre lo que se supone que debe hacer el usuario en la aplicación Configuración en función de la versión de iOS que está utilizando. Si alguien quiere dejar un comentario a continuación diciéndonos a todos qué versión exacta de iOS cambió, sería genial.
Swift 4:
En la parte superior de su controlador de vista:
import AVFoundation
Antes de abrir la vista de la cámara:
@IBAction func goToCamera()
{
let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
switch (status)
{
case .authorized:
self.popCamera()
case .notDetermined:
AVCaptureDevice.requestAccess(for: AVMediaType.video) { (granted) in
if (granted)
{
self.popCamera()
}
else
{
self.camDenied()
}
}
case .denied:
self.camDenied()
case .restricted:
let alert = UIAlertController(title: "Restricted",
message: "You''ve been restricted from using the camera on this device. Without camera access this feature won''t work. Please contact the device owner so they can give you access.",
preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
Alerta de denegación con bloqueo de finalización:
func camDenied()
{
DispatchQueue.main.async
{
var alertText = "It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:/n/n1. Close this app./n/n2. Open the Settings app./n/n3. Scroll to the bottom and select this app in the list./n/n4. Turn the Camera on./n/n5. Open this app and try again."
var alertButton = "OK"
var goAction = UIAlertAction(title: alertButton, style: .default, handler: nil)
if UIApplication.shared.canOpenURL(URL(string: UIApplicationOpenSettingsURLString)!)
{
alertText = "It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:/n/n1. Touch the Go button below to open the Settings app./n/n2. Turn the Camera on./n/n3. Open this app and try again."
alertButton = "Go"
goAction = UIAlertAction(title: alertButton, style: .default, handler: {(alert: UIAlertAction!) -> Void in
UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: nil)
})
}
let alert = UIAlertController(title: "Error", message: alertText, preferredStyle: .alert)
alert.addAction(goAction)
self.present(alert, animated: true, completion: nil)
}
}
C objetivo:
En la parte superior de su controlador de vista:
#import <AVFoundation/AVFoundation.h>
Antes de abrir la vista de la cámara:
- (IBAction)goToCamera
{
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(authStatus == AVAuthorizationStatusAuthorized)
{
[self popCamera];
}
else if(authStatus == AVAuthorizationStatusNotDetermined)
{
NSLog(@"%@", @"Camera access not determined. Ask for permission.");
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted)
{
if(granted)
{
NSLog(@"Granted access to %@", AVMediaTypeVideo);
[self popCamera];
}
else
{
NSLog(@"Not granted access to %@", AVMediaTypeVideo);
[self camDenied];
}
}];
}
else if (authStatus == AVAuthorizationStatusRestricted)
{
// My own Helper class is used here to pop a dialog in one simple line.
[Helper popAlertMessageWithTitle:@"Error" alertText:@"You''ve been restricted from using the camera on this device. Without camera access this feature won''t work. Please contact the device owner so they can give you access."];
}
else
{
[self camDenied];
}
}
Alerta de denegación:
- (void)camDenied
{
NSLog(@"%@", @"Denied camera access");
NSString *alertText;
NSString *alertButton;
BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
if (canOpenSettings)
{
alertText = @"It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:/n/n1. Touch the Go button below to open the Settings app./n/n2. Turn the Camera on./n/n3. Open this app and try again.";
alertButton = @"Go";
}
else
{
alertText = @"It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:/n/n1. Close this app./n/n2. Open the Settings app./n/n3. Scroll to the bottom and select this app in the list./n/n4. Turn the Camera on./n/n5. Open this app and try again.";
alertButton = @"OK";
}
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Error"
message:alertText
delegate:self
cancelButtonTitle:alertButton
otherButtonTitles:nil];
alert.tag = 3491832;
[alert show];
}
Llamada de delegado para UIAlertView:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 3491832)
{
BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
if (canOpenSettings)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}
}
Para Swift 3.0
Esto llevará al usuario a la configuración para cambiar el permiso.
func checkCameraAuthorise() -> Bool {
let status = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
if status == .restricted || status == .denied {
let dialog = ZAlertView(title: "", message: "Please allow access to the camera in the device''s Settings -> Privacy -> Camera", isOkButtonLeft: false, okButtonText: "OK", cancelButtonText: "Cancel", okButtonHandler:
{ _ -> Void in UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)}, cancelButtonHandler: { alertView in alertView.dismissAlertView() })
dialog.show()
return false
}
return true
}
Una vez que han denegado el acceso a la cámara, el usuario puede autorizar el uso de la cámara para su aplicación en Configuración. Por diseño, no puede anular esto en su propio código.
Puede detectar este caso con el siguiente código de muestra y luego explicarle al usuario cómo solucionarlo: iOS 7 UIImagePickerController Camera Sin imagen
NSString *mediaType = AVMediaTypeVideo; // Or AVMediaTypeAudio
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
// The user has explicitly denied permission for media capture.
else if(authStatus == AVAuthorizationStatusDenied){
NSLog(@"Denied");
}