iOS Camera permissions doesn't appear under settings in some devices

11,030

Solution 1

You need to request permission before opening a session. Use

[AVCaptureDevice requestAccessForMediaType:completionHandler:]

Solution 2

Step 1: Give a proper camera message access message on your info.plist using the following key (without quotes)

"Privacy - Camera Usage Description"

Step 2 : For objective-C/SWIFT you need to request a camera access permission

OBJECTIVE-C

[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted)
        {
            if (granted == true)
            {
                //[self presentViewController           : picker animated:YES completion:NULL];
               //Do your stuff

            }
            else
            {
                UIAlertView *cameraAlert = [[UIAlertView alloc]initWithTitle:STR_APPLICATION_TITLE
                                                                     message:STR_ALERT_CAMERA_DENIED_MESSAGE
                                                                    delegate:self
                                                           cancelButtonTitle:@"OK"
                                                           otherButtonTitles:nil,nil];
                [cameraAlert show];

                NSLog(@"denied");
            }

        }];

SWIFT

AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in
        if (videoGranted) {
             //Do Your stuff here

        } else {
            // Rejected Camera
        }
    })

Solution 3

I need the camera to user ARKit. Every time the vc with sceneView is shown I run the checkCameraPermission() in viewWillAppear. If the user doesn't allow access an alert will show with a settingsButton. Once they press that button they will be taken to Settings and the camera icon with the toggle switch will always be there.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    checkCameraPermission()
}

func checkCameraPermission() {

    let authorizationStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
    switch authorizationStatus {

    case .notDetermined:
        AVCaptureDevice.requestAccess(for: AVMediaType.video) { [weak self](granted) in
            if granted {
                print("access granted")
                DispatchQueue.main.async { [weak self] in
                    self?.startSceneViewSession()
                }

            } else {
                print("access denied")
                DispatchQueue.main.async { [weak self] in
                    self?.alertUserCameraPermissionMustBeEnabled()
                }
            }
        }

    case .authorized:
        print("Access authorized")
        startSceneViewSession()

    case .denied, .restricted:
        print("restricted")
        alertUserCameraPermissionMustBeEnabled()

    @unknown default:
        fatalError()
    }
}

func alertUserCameraPermissionMustBeEnabled() {

    let message = "Camera access is necessary to use Augemented Reality for this app.\n\nPlease go to Settings to allow access to the Camera.\n Please switch the button to the green color."

    let alert = UIAlertController (title: "Camera Access Required", message: message, preferredStyle: .alert)

    let settingsAction = UIAlertAction(title: "Settings", style: .default, handler: { (action) in

        guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }

        if UIApplication.shared.canOpenURL(settingsUrl) {
            UIApplication.shared.open(settingsUrl, completionHandler: { (_) in
            })
        }
    })

    alert.addAction(settingsAction)

    present(alert, animated: true, completion: nil)
}

// this is for ARKit
func startSceneViewSession() {
    sceneView.session.run(configuration)
    sceneView.isPlaying = true
}
Share:
11,030
lucaslt89
Author by

lucaslt89

I'm an iOS software engineer, passionate about innovation and new technologies. I'm always trying to use latest technologies and techniques in the products i develop.

Updated on July 19, 2022

Comments

  • lucaslt89
    lucaslt89 almost 2 years

    I'm having some issues trying to use the camera. The problem is that some devices show me the Camera entry under settings, and some others don't. In those devices where the Camera switch doesn't appear, I'm not able to use the camera, since it doesn't have permissions, and it also doesn't appear under settings to enable them.

    This is how it looks on a device that works:

    enter image description here

    And this is how it looks in devices that doesn't work.

    enter image description here

    When I took those screenshots, the application should've asked for permissions already, but it didn't.

    I also verified that those devices doesn't have Restrictions enabled.

    Any ideas?

    UPDATE 1: Added code

    This is the code I'm using to show the camera (it's under a custom view, not the native camera view controller)

    self.captureSession = [[AVCaptureSession alloc] init];
    AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error];
    if(videoInput)
    {
        [self.captureSession addInput:videoInput];
    }
    else
    {
        NSLog(@"Error: %@", error);
    }
    
    AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init];
    [self.captureSession addOutput:metadataOutput];
    [metadataOutput setMetadataObjectsDelegate:self
                                         queue:dispatch_get_main_queue()];
    [metadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeQRCode]];
    
    AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
    previewLayer.frame = self.view.layer.bounds;
    UIView * previewView = [[UIView alloc] initWithFrame:self.view.frame];
    [previewView.layer addSublayer:previewLayer];
    [self.view addSubview:previewView];
    [self.view sendSubviewToBack:previewView];
    
    [self.captureSession startRunning];
    
  • durazno
    durazno over 8 years
    No this is not true. "Note that the authorization dialog will automatically be shown if the status is AVAuthorizationStatusNotDetermined when creating an AVCaptureDeviceInput." and it does exactly that if you don't manually ask for permission and also you do get asked when manually done. However I'm having the same issue with lucaslt89. Even after resetting location & privacy, the app doesn't request permission and the same result when manually called [AVCaptureDevice requestAccessForMediaType:completionHandler:]. This happens with some devices but with some others no such issue occurs. WHY?!!
  • abhimuralidharan
    abhimuralidharan over 8 years
    I am also having the same issue.the app doesn't request permission .Have you corrected it?
  • Chathura Palihakkara
    Chathura Palihakkara about 4 years
    Can you guys help to confirm this issue is happening on multi camera iPhones with iOS 13 ???