Requesting user authorization for privacy-protected frameworks

Requesting user authorization for privacy-protected frameworks

Discover how to ask for privacy authorization to manage the current authentication status.

Access to system resources (camera, microphone), user device data (health), and system services (contacts, calendar) requires user authorization. There are many ways of keeping track of your app's current authorization status for accessing a particular resource of the user’s device or account.

This article has the goal of suggesting a method for tracking these statuses.

In the article Camera capture setup in a SwiftUI app we needed to access the camera of the device where the app is running.

To access the camera resource you must request and obtain the user's authorization. The proposed implementation of the article creates a computed property that is responsible for returning the current status of the authorization and requesting it if the user has not provided authorization yet:

private var isAuthorized: Bool {
    get async {
        let status = AVCaptureDevice.authorizationStatus(for: .video)
            
        // Determine if the user previously authorized camera access.
        var isAuthorized = status == .authorized
            
        // If the system hasn't determined the user's authorization status,
        // explicitly prompt them for approval.
        if status == .notDetermined {
            isAuthorized = await AVCaptureDevice.requestAccess(for: .video)
        }
            
        return isAuthorized
    }
}

This snippet above is originally presented in an article in the AVFoundation framework documentation.

The possible types of authorization status for an AVCaptureDevice are defined by the AVAuthorizationStatus type and can be:

If your project doesn’t require you to track complex combinations of authorization statuses to provide access to its core features, this might be the best way to implement an authorization check.

The advantages are:

  • All the logic is contained in a convenient computed property.
  • The property provides only the information that is needed, a boolean value saying if the user has authorized or not the usage of that resource
  • If the authorization status is notDetermined, it prompts the authorization request. This provides an easy way to manage the request and also avoids the need to have a different portion of code responsible for it.
  • This implementation uses Swift structured concurrency, async/await, with all its benefits. There is no need to address completion handlers.

Other scenarios

Even though an implementation with a computed property is simple, it may not be ideal for every scenario since a single computed property takes the responsibility for returning a Bool value while also making the request for authorization in case it has not been made before.

The variable hides the part where the complexity is, making it opaque. Depending on the project you are working on, and the way the development team works, refactoring may be necessary.

For more complex scenarios, structure your code in a way that it is clear which object or method is responsible for calling the function that requests access to the required resource.

Also, incorporate good design practices in your user flow. The Human Interface Guidelines suggest how to create a good UX flow so that the user is more likely to permit you.

Privacy | Apple Developer Documentation
Privacy is paramount: it’s critical to be transparent about the privacy-related data and resources you require and essential to protect the data people allow you to access.