iOS Camera Permissions

Predictive Document Verification (DocV) iOS SDKs that capture documents or images require access to the device camera. On iOS, camera access is fully controlled by the operating system and gated by explicit user consent.

If camera access isn’t granted, document capture cannot proceed.


How iOS camera permissions work

iOS shows the system camera permission prompt once per app:

App Name would like to access the camera”

If the user taps Don’t Allow, iOS will not show the prompt again automatically. The SDK cannot re-request permission on your behalf. Only the user can re-enable camera access from Settings.

Your app must detect this state and guide the user accordingly.


Camera authorization states

Camera access can be in one of four states:

StateMeaningWhat you can do
notDeterminedUser has not been prompted yetYou may request access (system prompt appears)
authorizedUser granted accessCamera capture can proceed
deniedUser denied accessUser must enable access in Settings
restrictedAccess blocked by system policy (MDM, parental controls)Cannot be resolved programmatically

Required configuration

Before using any DocV SDK feature that accesses the camera, your app must declare a camera usage description in Info.plist.

<key>NSCameraUsageDescription</key>
<string>Camera access is required to capture documents for identity verification.</string>

If this key is missing:

  • iOS will terminate the app when camera access is attempted.
  • The DocV SDK will not be able to start a capture session.

Recommended integration patterns

Option 1 — Handle permission denial after SDK launch

If the DocV SDK returns an error indicating camera access was declined, your app should:

  1. Detect the permission-denied error.
  2. Explain why camera access is required.
  3. Provide a clear path to Settings.

Suggested copy

  • Title: Camera access needed
  • Message: Camera access is required to complete document capture. Enable it in Settings to continue.
  • Action: Open Settings

Option 2 — Pre-check permission before launching DocV (recommended)

This approach avoids starting a DocV session when camera access is unavailable.

Flow

  1. Check the current camera authorization state.
  2. If notDetermined, request permission (system prompt appears once).
  3. If denied or restricted, show your own UI and link to Settings.
  4. Launch DocV only after access is authorized.

Example implementation

This example pre-checks and requests camera permission before launching a DocV session.

import UIKit
import AVFoundation
import SocureDocV

class ViewController: UIViewController {

    @IBOutlet weak var lblStatus: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // MARK: - UI Helpers
    func updateStatus(_ status: String) {
        DispatchQueue.main.async { [weak self] in
            self?.lblStatus.text = status
        }
    }

    // MARK: - Camera Permission Handling
    private func checkAndRequestCameraPermission(
        completion: @escaping (Bool) -> Void
    ) {
        let status = AVCaptureDevice.authorizationStatus(for: .video)

        switch status {
        case .notDetermined:
            // First time: show the system prompt
            AVCaptureDevice.requestAccess(for: .video) { granted in
                DispatchQueue.main.async {
                    if granted {
                        completion(true)
                    } else {
                        self.showCameraDeniedAlert(firstTime: true)
                        completion(false)
                    }
                }
            }

        case .authorized:
            // Already allowed → good to go
            completion(true)

        case .denied, .restricted:
            // User denied previously, or device restrictions apply
            showCameraDeniedAlert(firstTime: false)
            completion(false)

        @unknown default:
            completion(false)
        }
    }

    private func showCameraDeniedAlert(firstTime: Bool) {
        let title = "Camera Access Needed"
        let message: String

        if firstTime {
            message = "Camera access is required to complete the document capture. Please enable it in Settings if you’d like to proceed."
        } else {
            message = "Camera access has been disabled for this app. Please go to Settings → Privacy → Camera and enable access to continue."
        }

        let alert = UIAlertController(
            title: title,
            message: message,
            preferredStyle: .alert
        )

        // Open Settings button
        let settingsAction = UIAlertAction(
            title: "Open Settings",
            style: .default
        ) { _ in
            guard let settingsURL = URL(
                string: UIApplication.openSettingsURLString
            ) else { return }

            if UIApplication.shared.canOpenURL(settingsURL) {
                UIApplication.shared.open(
                    settingsURL,
                    options: [:],
                    completionHandler: nil
                )
            }
        }

        let cancelAction = UIAlertAction(
            title: "Cancel",
            style: .cancel,
            handler: nil
        )

        alert.addAction(settingsAction)
        alert.addAction(cancelAction)
        present(alert, animated: true, completion: nil)
    }

    // MARK: - DocV Launch
    private func startDocVFlow() {
        let options = SocureDocVOptions(
            publicKey: "YOUR_PUBLIC_KEY",
            docvTransactionToken: "YOUR_TRANSACTION_TOKEN",
            presentingViewController: self,
            useSocureGov: false
        )

        SocureDocVSDK.launch(options) { [weak self] result in
            switch result {
            case .success(let successResult):
                self?.updateStatus("Upload Success: \(successResult)")
                print(successResult)

            case .failure(let failureResult):
                self?.updateStatus("Upload Failure: \(failureResult.error)")
                print(failureResult)
            }
        }
    }

    // MARK: - IBActions
    @IBAction func startScan(_ sender: Any) {
        // 1) Check / request camera permission
        checkAndRequestCameraPermission { [weak self] granted in
            guard let self = self else { return }

            if granted {
                // 2) If granted, start the DocV flow
                self.startDocVFlow()
            } else {
                self.updateStatus("Camera permission not granted")
            }
        }
    }
}

Key points in the example

  • Check authorization state first using AVCaptureDevice.authorizationStatus(for: .video).
  • Only request permission when status is notDetermined. This is the only state that can trigger the system prompt.
  • Handle denied and restricted with app-owned UI and a clear path to Settings.
  • Deep-link to Settings with UIApplication.openSettingsURLString.
  • Launch DocV only when granted to avoid dead-end sessions.
  • Update UI on the main thread and avoid retain cycles with [weak self].

Best practices

  • Use a clear, single-purpose message: “Camera access is required to capture your document.”
  • Keep the CTA consistent: Open Settings.
  • If the user returns from Settings without granting permission, re-check the status and keep guidance visible.
  • Consider tracking denial-related analytics (for example: permission_denied, opened_settings) to identify drop-off points.