Hand tracking authorization request not working after initial attempt?

When I first install and run the app, it requests authorization for hand tracking data. But then if I go to the settings and disable hand tracking from the app, it no longer requests. The output of requestAuthorization(for:) method just says [handTracking : denied]

Any idea why the push request only shows up once then never again?

Answered by Vision Pro Engineer in 808454022

Hi @ericD_TRI ,

Yep, that's expected behavior. Once it's denied by the user in settings, you'll need to handle that case in your code when you check if the user is authorized. I'd do something like this:

func setUpSession() async {
  
      // If we have the required authorizations immediately run the session
      let authRes = await session.queryAuthorization(for: HandTrackingProvider.requiredAuthorizations)
      if hasRequiredAuthorizations(authorizationResult: authRes) {
        await start()
      } else {
        // else request the required authorizations
        let requestedResult = await session.requestAuthorization(for: HandTrackingProvider.requiredAuthorizations)
        if requestedResult.allSatisfy( { $0.value == .denied } ) {

// Here, you would open a new window with this id that mentions that the user needs to go to Settings and allow the hand tracking.
          openWindow(id: “permissionDenied”)

        }

        // and if the user grants them, run the session.
        if hasRequiredAuthorizations(authorizationResult: requestedResult) {
          await start()
        }
      }
     
  }
  func hasRequiredAuthorizations(authorizationResult: [ARKitSession.AuthorizationType : ARKitSession.AuthorizationStatus]) -> Bool {
    HandTrackingProvider.requiredAuthorizations
      .map { authorizationResult[$0] ?? ARKitSession.AuthorizationStatus.notDetermined }
      .allSatisfy { $0 == .allowed }
  }

This snippet uses openWindow to open a window telling the user to go to setting and turn back on the toggle. You can also use Link to send them straight to settings in the new window:

Link("go to settings", destination: URL(string: UIApplication.openSettingsURLString)!)

Clicking this will take them to your app's settings.

Accepted Answer

Hi @ericD_TRI ,

Yep, that's expected behavior. Once it's denied by the user in settings, you'll need to handle that case in your code when you check if the user is authorized. I'd do something like this:

func setUpSession() async {
  
      // If we have the required authorizations immediately run the session
      let authRes = await session.queryAuthorization(for: HandTrackingProvider.requiredAuthorizations)
      if hasRequiredAuthorizations(authorizationResult: authRes) {
        await start()
      } else {
        // else request the required authorizations
        let requestedResult = await session.requestAuthorization(for: HandTrackingProvider.requiredAuthorizations)
        if requestedResult.allSatisfy( { $0.value == .denied } ) {

// Here, you would open a new window with this id that mentions that the user needs to go to Settings and allow the hand tracking.
          openWindow(id: “permissionDenied”)

        }

        // and if the user grants them, run the session.
        if hasRequiredAuthorizations(authorizationResult: requestedResult) {
          await start()
        }
      }
     
  }
  func hasRequiredAuthorizations(authorizationResult: [ARKitSession.AuthorizationType : ARKitSession.AuthorizationStatus]) -> Bool {
    HandTrackingProvider.requiredAuthorizations
      .map { authorizationResult[$0] ?? ARKitSession.AuthorizationStatus.notDetermined }
      .allSatisfy { $0 == .allowed }
  }

This snippet uses openWindow to open a window telling the user to go to setting and turn back on the toggle. You can also use Link to send them straight to settings in the new window:

Link("go to settings", destination: URL(string: UIApplication.openSettingsURLString)!)

Clicking this will take them to your app's settings.

Hand tracking authorization request not working after initial attempt?
 
 
Q