Skip to main content

Working with Permissions

1. Requesting Camera Permission

Permission Key Description Status
NSCameraUsageDescription NSCameraUsageDescription Explains why the app needs access to the camera NEW

Example: Requesting Camera Permission

import AVFoundation
import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        requestCameraPermission()
    }

    func requestCameraPermission() {
        AVCaptureDevice.requestAccess(for: .video) { granted in
            DispatchQueue.main.async {
                if granted {
                    print("Camera access granted")
                } else {
                    print("Camera access denied")
                }
            }
        }
    }
}
Note: The app must include the NSCameraUsageDescription key in its Info.plist or it will be rejected during App Store submission.

2. Requesting Photo Library Access

Permission Usage Notes
PHPhotoLibrary.readWriteUsageDescription NSPhotoLibraryUsageDescription Required for read/write access to the photo library
PHPhotoLibrary.readOnlyUsageDescription NSPhotoLibraryAddUsageDescription Required for read-only access to the photo library

Example: Requesting Photo Library Access

import Photos

func requestPhotoLibraryAccess() {
    PHPhotoLibrary.requestAuthorization(.readWrite) { status in
        switch status {
        case .authorized:
            print("Access granted")
        case .denied, .restricted:
            print("Access denied or restricted")
        case .notDetermined:
            print("Not determined yet")
        @unknown default:
            print("Unknown status")
        }
    }
}
Note: You must add the appropriate NSPhotoLibraryUsageDescription key to your app's Info.plist with a user-facing message explaining why the app needs access to the photo library.

3. Requesting Location Services

Permission Usage Notes
NSLocationWhenInUseUsageDescription Info.plist Required for location access when app is in use
NSLocationAlwaysAndWhenInUseUsageDescription Info.plist Required for background location access

Example: Requesting Location Permission

import CoreLocation

class LocationManager: NSObject, CLLocationManagerDelegate {
    private let locationManager = CLLocationManager()

    override init() {
        super.init()
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .authorizedWhenInUse, .authorizedAlways:
            print("Location access granted")
        case .denied, .restricted:
            print("Location access denied")
        default:
            print("Location access not determined")
        }
    }
}
Note: Always include the appropriate Info.plist keys with descriptive messages for permission requests.

4. Requesting Microphone Permission

Permission Key Usage Notes
NSMicrophoneUsageDescription string Required description shown to user when requesting microphone access

Example: Requesting Microphone Access

import AVFoundation

let audioSession = AVAudioSession.sharedInstance()
do {
    try audioSession.setCategory(.playAndRecord, options: .defaultToSpeaker)
    try audioSession.setActive(true)
} catch {
    print("Failed to set up audio session: \(error)")
}
Note: The app must include the NSMicrophoneUsageDescription key in its Info.plist with a user-facing message explaining why the microphone is needed.
Warning: If the user denies microphone access, the app should gracefully handle this and provide alternative functionality or clear messaging.

5. Requesting Contacts Access

Permission Usage Description
NSContactsUsageDescription Info.plist Explain why your app needs access to contacts. Required for iOS 10+.

Example: Requesting Contacts Permission

import Contacts

let store = CNContactStore()
store.requestAccess(for: .contacts) { granted, error in
    if granted {
        print("Access granted")
    } else {
        print("Access denied")
    }
}
Note: The app must include the NSContactsUsageDescription key in its Info.plist with a user-facing description of why the permission is needed.

6. Requesting Calendar and Reminders

Permission Identifier Description Status
Calendar SKPermission.Calendar Access to calendar events and reminders NEW
Reminders SKPermission.Reminders Access to reminders and to-dos NEW

Example: Requesting Calendar Permission

import EventKit

let eventStore = EKEventStore()
eventStore.requestAccess(to: .event) { granted, error in
    if granted {
        print("Calendar access granted")
    } else {
        print("Calendar access denied")
    }
}

Example: Requesting Reminders Permission

import EventKit

let eventStore = EKEventStore()
eventStore.requestAccess(to: .reminder) { granted, error in
    if granted {
        print("Reminders access granted")
    } else {
        print("Reminders access denied")
    }
}
Note: You must add the NSCalendarsUsageDescription key to your app's Info.plist with a description of why you need calendar access.
Note: You must add the NSRemindersUsageDescription key to your app's Info.plist with a description of why you need reminders access.

7. Requesting Notifications Permission

Permission Identifier Description Required in Info.plist
notifications UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge Allows displaying alerts, playing sounds, and updating badges No

Example: Requesting Notification Permission

import UserNotifications

func requestNotificationPermission() {
    let options: UNAuthorizationOptions = [.alert, .sound, .badge]
    UNUserNotificationCenter.current().requestAuthorization(options: options) { granted, error in
        if granted {
            print("Notification permission granted.")
        } else {
            print("Notification permission denied.")
        }
    }
}
Note: The first time a user is prompted for notification permissions, the system will show a native dialog asking them to allow or deny notifications. This should only be called after the app is in the foreground and ready to handle the response.

8. Checking Permission Status

Permission Status Description
NSCameraUsageDescription authorized, denied, notDetermined User has granted or denied camera access
NSLocationWhenInUseUsageDescription authorized, denied, notDetermined Location access when app is in use
NSMicrophoneUsageDescription authorized, denied, notDetermined Microphone access for recording
NSPhotoLibraryUsageDescription authorized, denied, notDetermined Access to user's photo library

Example: Check Camera Permission Status

import AVFoundation

func checkCameraPermission() {
    let status = AVCaptureDevice.authorizationStatus(for: .video)
    switch status {
    case .authorized:
        print("Camera access granted")
    case .denied:
        print("Camera access denied by user")
    case .notDetermined:
        print("Permission not yet requested")
    default:
        print("Other status: \(status)")
    }
}

Example: Check Location Permission Status

import CoreLocation

let locationManager = CLLocationManager()

func checkLocationPermission() {
    let status = locationManager.authorizationStatus
    switch status {
    case .authorizedWhenInUse:
        print("Location access granted for in-use")
    case .denied:
        print("Location access denied by user")
    case .notDetermined:
        print("Permission not yet requested")
    default:
        print("Other status: \(status)")
    }
}

9. Handling Permission Denials

Example: Requesting Location Permission with Error Handling

import CoreLocation

class LocationManager: NSObject, CLLocationManagerDelegate {
    private let locationManager = CLLocationManager()

    func requestLocationPermission() {
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .denied, .restricted:
            handlePermissionDenied()
        case .authorizedWhenInUse, .authorizedAlways:
            // Proceed with location usage
            print("Location access granted")
        default:
            break
        }
    }

    private func handlePermissionDenied() {
        // Show alert to user or redirect to settings
        print("Location permission denied by user")
    }
}
Authorization Status Description Action Required
.denied User has explicitly denied permission Inform user and suggest enabling in Settings
.restricted Permission is restricted (e.g., parental controls) Inform user and suggest enabling in Settings
.notDetermined User has not yet responded to the permission request Request authorization again
.authorizedWhenInUse Permission granted for use when app is in foreground Proceed with location services
.authorizedAlways Permission granted for use in background Proceed with location services
Note: On iOS, once a user denies permission, they must manually re-enable it in Settings. There's no way to programmatically re-prompt for permission.

Workflow: Handling Permission Denial

  1. User denies permission in system dialog
  2. App receives .denied status in didChangeAuthorization
  3. App informs user that permission is required for feature to work
  4. App offers option to navigate to Settings
  5. User enables permission in Settings

Comparison: Permission Types

  • When In Use: Access while app is in foreground
  • Always: Access both foreground and background
  • Denied: User has explicitly declined
  • Restricted: Parental controls or device restrictions

10. Using Info.plist Usage Descriptions

When requesting permissions for sensitive iOS features, you must provide a usage description in your app's Info.plist file. These descriptions are displayed to users when the system prompts them for permission.

Permission Info.plist Key Description
Camera NSCameraUsageDescription Explains why your app needs access to the camera.
Microphone NSMicrophoneUsageDescription Explains why your app needs access to the microphone.
Photo Library NSPhotoLibraryUsageDescription Explains why your app needs access to the photo library.
Location (When In Use) NSLocationWhenInUseUsageDescription Explains why your app needs location access while in use.
Location (Always and When In Use) NSLocationAlwaysAndWhenInUseUsageDescription Explains why your app needs location access at all times.
Contacts NSContactsUsageDescription Explains why your app needs access to the user's contacts.
Calendar NSCalendarsUsageDescription Explains why your app needs access to the user's calendar.
Reminders NSRemindersUsageDescription Explains why your app needs access to the user's reminders.
Motion NSMotionUsageDescription Explains why your app needs access to motion data.
Bluetooth NSBluetoothAlwaysUsageDescription Explains why your app needs access to Bluetooth.

Example: Adding Usage Description to Info.plist

<key>NSCameraUsageDescription</key>
<string>This app uses the camera to take photos for your profile.</string>
Note: If a usage description is missing, iOS will deny permission requests and show a generic error to the user.

Was this article helpful?