iosswiftswiftuiuikit

Can't request `always` location authorization


I'm trying to request always access to location updates. According to Apple's documentation, I need to add the key NSLocationAlwaysAndWhenInUseUsageDescription to my info.plist and call requestAlwaysAuthorization() on my CLLocationManager.

However, this simply don't work. There's no authorization request popups nor any error messages:

ContentView()
    .onAppear {
        CLLocationManager().requestAlwaysAuthorization()
    }

enter image description here

It DOES work when I change the info.plist key to NSLocationWhenInUseUsageDescription and call requestWhenInUseAuthorization() instead.

What am I doing wrong?


EDIT:

I also tried adding "Location updates" capabilities:

enter image description here


Solution

  • I think Apple's documentation needs improvement here, as you need to dig through several pages to find the right way to do it. But it might be hard to follow on purpose.

    1. First, there is this article Choosing the Location Services Authorization to Request. It basically says you can request a Always authorization by itself, so you are correct on that regard.
    2. How to request the Always authorization then? It leads to this API page: requestAlwaysAuthorization. In this page, it reads

    You must call this or the requestWhenInUseAuthorization() method before your app can receive location information. To call this method, you must have both NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription keys in your app’s Info.plist file.

    1. Finally, there is the difference between macOS and iOS. If your app is multi-platform, you'll learn the hard way how much hassle it takes to get through App Store Connect. But that is a story for another time.

    Think of it this way - the "When In Use" authorization is the base case for all authorization. You must present that alert as the first step for location permissions.

    Furthermore, even if you have requested and got granted the "Always" permission, iOS will still prompt the user at random future times with the "Change to Only While Using" alert.

    So you get the idea… Apple just doesn't want you to use "Always".