Best Practice way to handle locationAlways permission request

Hi there,

How are we supposed to handle, when a user denies the permission request for kCLAuthorizationStatusAuthorizedAlways ? As i understand it, we don't get a direct response to requestAlwaysAuthorization, but rather we have to register a callback for locationManagerDidChangeAuthorization, which only gets called, if status is undetermined or is changed. Since we first have to request whenInUse permission with requestWhenInUseAuthorization, the status is no longer undetermined once we request always permission. Furthermore, since the "deny" option is "keep when in use permission", the actual permission is not changed if the request is denied, hence the callback won't be called. So how are we supposed to know the request was denied by the user, so we can point them towards the settings ?

A bit of context: I am developing an App in Flutter, where I need the kCLAuthorizationStatusAuthorizedAlways. For this, I use a library called permission_handler, which has native (objective c) code for iOS. Sadly, it has a bug, and since I need it to work, I am going to try to fix it myself.

Looking through the code, I suspect the problem stems from the callback not being called in the "deny" case, so I am trying to figure out how to obtain the information, that the request was denied, so I can return this information from the plugin to the FlutterEngine, where my flutter code is run.

You don't have to understand any Flutter or Dart to explain/understand this, as I just want to know how you would handle this situation in a native iOS app, so I can understand it and apply that knowledge to my flutter app/the library.

Thanks for taking the time to read my question and helping me!

What an app is expected to do when the "Always" authorization is denied is, to respect the users' choice and not turn back and insist on getting the Always authorization. Hence, the lack of a mechanism that will alert the app in order to send the user to settings and ask them to change their decision as soon as they make it.

If and when your app is launched by the user after they deny the request, you can check the location manager instance's .authorizationStatus property to determine the current authorization and enable or disable features in your app accordingly.

I understand where you coming from, but since I can still check (although more difficult/cumbersome) the authorizationStatus, thus invalidating the "respect the user's choice" part, I think this is just making it unnecessarily complicated for the developer. And, while i strongly agree with principle of not forcing unnecessary permissions onto the user, sometimes these permission are simply not optional. If the core feature of my app is some cool automatic GPS tracking feature, then the user might aswell uninstall the app if he does not permit the authorization for it.

For now though, I think I have found a solution for the issue, so I can fix the bug in the library and send them a PR. My idea was to just hook into the NSNotificationCenter and add an observer for UIApplicationDidBecomeActiveNotification, since this should be triggered once the permission dialog is closed. From manually debugging, it seems that didChangeAuthorizationStatus gets called before the observer, so once the observer is called, it can verify whether the callback has been called, and thus I have my callback for the case of a denied permission dialog.

This way I can keep the behaviour of the library code inline with behaviour of the Android side of things, and therefore won't need to differentiate between platforms in the flutter code, which was the ultimate goal of this.

Best Practice way to handle locationAlways permission request
 
 
Q