Camera & Permissions
The Circadify SDK requires access to the front-facing camera. iOS enforces strict permission controls — your app must handle the permission flow before starting a measurement.
Info.plist
Section titled “Info.plist”Add the camera usage description to your Info.plist. Without this, iOS will terminate your app on camera access.
<key>NSCameraUsageDescription</key><string>This app uses the camera to measure your vital signs contactlessly.</string>Write a clear, specific description. Vague descriptions like “Camera access needed” may cause App Store review rejection.
Permission Flow
Section titled “Permission Flow”-
Check the current permission status with
checkCameraPermission(). -
Request permission if the status is
.notDetermined. This shows the system dialog. -
Handle denial — if the user denied permission, guide them to Settings. iOS won’t show the dialog again.
import CircadifySDK
struct ScanView: View { @State private var permissionGranted = false @State private var showSettingsAlert = false
let sdk = try! CircadifySDK(apiKey: "ck_test_your_key_here")
var body: some View { VStack { if permissionGranted { // Show scan UI Text("Ready to scan") } else { Button("Enable Camera") { Task { await requestPermission() } } } } .alert("Camera Access Required", isPresented: $showSettingsAlert) { Button("Open Settings") { if let url = URL(string: UIApplication.openSettingsURLString) { UIApplication.shared.open(url) } } Button("Cancel", role: .cancel) { } } message: { Text("Go to Settings > Privacy > Camera and enable access for this app.") } .task { checkPermission() } }
func checkPermission() { let status = sdk.checkCameraPermission() permissionGranted = (status == .authorized) }
func requestPermission() async { let status = sdk.checkCameraPermission()
switch status { case .notDetermined: permissionGranted = await sdk.requestCameraPermission() if !permissionGranted { showSettingsAlert = true } case .denied, .restricted: showSettingsAlert = true case .authorized: permissionGranted = true @unknown default: break } }}import CircadifySDK
class ScanViewController: UIViewController { let sdk = try! CircadifySDK(apiKey: "ck_test_your_key_here")
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) checkAndRequestPermission() }
func checkAndRequestPermission() { let status = sdk.checkCameraPermission()
switch status { case .authorized: enableScanButton() case .notDetermined: Task { let granted = await sdk.requestCameraPermission() DispatchQueue.main.async { if granted { self.enableScanButton() } else { self.showSettingsAlert() } } } case .denied, .restricted: showSettingsAlert() @unknown default: break } }
func showSettingsAlert() { let alert = UIAlertController( title: "Camera Access Required", message: "Go to Settings > Privacy > Camera and enable access for this app.", preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { _ in if let url = URL(string: UIApplication.openSettingsURLString) { UIApplication.shared.open(url) } }) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) present(alert, animated: true) }}Best Practices
Section titled “Best Practices”- Check before measuring. Always call
checkCameraPermission()beforemeasureVitals(). The SDK will throwCircadifyError.cameraPermissionDeniedif permission hasn’t been granted, but handling it proactively gives a better user experience. - Request early. Ask for permission during onboarding or before the scan screen, not at the last moment.
- Handle denial gracefully. Provide a clear path to Settings with a direct deep link (
UIApplication.openSettingsURLString). - Listen for app foreground. After the user returns from Settings, re-check permission in
sceneDidBecomeActiveor.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)).
Next Steps
Section titled “Next Steps”- Methods — Start a measurement
- Error Handling — Handle permission-related errors
- Configuration — SDK setup options