Long story short:
I'd like to make "Location" appear in the app settings without requesting for location authorization, like the Tile app does.
Steps to reproduce:
- Install the Tile app.
- There is no "Location" in the app settings.
- Open the app, accept Bluetooth access request (does it matter?).
- There is still no "Location" in the app settings, but Bluetooth appears.
- Use the app for about 20 seconds (can't be shorter).
- "Location" appears in the app settings - how?
This is presented on the video below:
https://media.giphy.com/media/h5dPQPbBHzEhdLTrKz/giphy.gif
How can I achieve this?
Background - why
Since iOS 13, the user cannot be asked for Always
location authorization directly. When the developer requests for Always
authorization, the user can select only While in Use
option and the app gets Provisional Always
authorization. Until the user is prompted again (iOS decides when), the user will see While in Use
authorization in the app settings.
Which means:
Always
-->CLAuthorizationStatus.authorizedAlways
andAlways
in the app settings.Provisional Always
--> alsoCLAuthorizationStatus.authorizedAlways
butWhile in Use
in the app settings.
This is well described in this Stack Overflow answer.
The problem is that the application cannot read the location in the background without Always
authorization (it can, but only for 5-10 seconds), which greatly limits the main functionality of some apps (e.g. iBeacon trackers).
A well-known practice is to check if the app has Always
authorization, and if not, present information describing why this is important and how the user can change it (manually in settings).
But we cannot distinguish if we have Always
or Provisional Always
authorization status (at least directly), so the logic:
if (CLLocationManager.authorizationStatus() != .authorizedAlways) {
// Prompt the user to change Location access to Always manually in settings
}
will not work for Provisional Always
authorization status.
The solution could be to ask the user to choose Always
manually in the settings before requesting location authorization, to prevent Provisional Always
state from happening. I thought it was impossible without calling requestAlwaysAuthorization()
first, but Tile somehow does it, as presented on the previous video.
Update:
I already have:
NSLocationAlwaysAndWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
privacy keys set in Info.plist file.