且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

有没有办法让用户在iOS上拒绝后才能访问相机?

更新时间:2023-12-02 10:25:58

经过一番研究后看起来像你不能做我想做的事。如果在iOS 8 +上,我编码弹出对话框并自动打开设置应用程序的替代方案。

After some research it looks like you can't do what I'd like. Here is the alternative that I coded to pop a dialog and open the Settings app automatically if on iOS 8+.

一些注意事项:


  • 从iOS 10开始,您需要在Info.plist中指定 NSCameraUsageDescription 键才能要求相机访问,否则您的应用程序将在运行时崩溃。

  • 一旦用户更改了您的应用程序的任何权限,它将终止您的应用程序。在用户点击开始按钮之前,请相应处理并保存所有必需的数据。

  • 在iOS 8和11之间的某个时刻,Apple不再要求用户触摸中的隐私单元格。设置应用以获取和更改相机设置。您可能希望根据用户使用的iOS版本更改用户在设置应用中应执行的操作的说明。如果有人想在下面发表评论告诉我们所有改变的iOS版本,那就太棒了。

  • Since iOS 10 you need to specify NSCameraUsageDescription key in your Info.plist to be able ask for camera access, otherwise your app will crash at runtime.
  • Once the user changes any permissions for your app, it will kill your app. Handle accordingly and save any needed data before the user hits that "Go" button.
  • At some point between iOS 8 and 11, Apple no longer required the user to touch the Privacy cell in the Setting apps in order to get to and change the Camera settings. You may want to change your instructions on what the user is supposed to do in the Settings app based on what iOS version they are using. If someone wants to leave a comment below telling us all what exact iOS version that changed in, that would be awesome.

Swift 4:

在视图控制器的顶部:

import AVFoundation

在打开相机视图之前:

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

完成块拒绝提醒:

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

Objective-C:

在视图控制器的顶部:

#import <AVFoundation/AVFoundation.h>

在打开相机视图之前:

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

拒绝提醒:

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

委托调用UIAlertView:

Delegate call for the UIAlertView:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if (alertView.tag == 3491832)
    {
        BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
        if (canOpenSettings)
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    }
}