ATT permission alert is not showing at serial permission prompt flow

First, I code ATT authorization struct below which uses brand new Swift concurrency.

struct ATT {
    private init() {}
   
    static func permissionRequest() async -> Bool {
        switch ATTrackingManager.trackingAuthorizationStatus {
        case .notDetermined:
            await ATTrackingManager.requestTrackingAuthorization()
            return ATTrackingManager.trackingAuthorizationStatus == .authorized
        case .restricted, .denied:
            return false
        case .authorized:
            return true
        @unknown default:
            fatalError()
        }
    }
}

And Video authorization as well.

struct Video {
    private init() {}

    static func permissionRequest() async -> Bool {
        switch AVCaptureDevice.authorizationStatus(for: .video) {
        case .authorized:
            return true
        case .denied, .restricted:
            return false
        case .notDetermined:
            await AVCaptureDevice.requestAccess(for: .video)
            return AVCaptureDevice.authorizationStatus(for: .video) == .authorized
        @unknown default:
            fatalError()
        }
    }
}

Next, I request two permissions in serial, and works as I expected.

Remember uninstalling the app to reset those permissions status.

@IBAction func onClickButton(_ sender: Any?) {
    Task {          
        _ = await ATT.permissionRequest()  // okay
        _ = await Video.permissionRequest() // okay
    }
}

Lastly, I replace those order, and ATT alert is not showing this time.

That’s not what I expected.

Why ?

@IBAction func onClickButton(_ sender: Any?) {
    Task {          
        _ = await Video.permissionRequest() // okay
        _ = await ATT.permissionRequest() // not showing
    }
}

And I noticed this would happen again when I called this from viewDidLoad()

override func viewDidLoad() {
    super.viewDidLoad()

    Task {
        _ = await ATT.permissionRequest()  // not showing
    }
}

Seems like this behavior is since iOS 15 beta 3.

Replies

I am experiencing the same problem, on iOS15 beta 5.

I am able to show the dialog when presented directly in for example viewDidAppear, but when showing in succession to other permission requests, and also when presenting after another functions block callback is returned, it doesn't show. When stepping through the methods in XCode I am able to see that requestTrackingAuthorization is executed and also returns a result, but the dialog doesn't show and the trackingStatus remains and NotDetermined.

Would love to see this fixed in the next beta.

I found the answer in developer documentation.

Apple say that "Calls to the API only prompt when the application state is: UIApplicationStateActive. Calls to the API through an app extension do not prompt.".

We have to check UIApplicationState before attempt to show the prompt.

  • Does that mean that when another permission request dialog is on the screen, the app considers itself in the background?

Add a Comment