7

When my app launches the map view, I request the iOS8 "When In Use" location permission. Assume user grants that.

I would like to request the Always permission only when user opts-in to my geofencing feature. But calling CLLocationManager.requestAlwaysAuthorization has no effect because the current authorization status is no longer kCLAuthorizationStatusNotDetermined.

How would one go about requesting the Always permission AFTER user has granted When In Use permission? I would think this is a common use case because apps should avoid asking for the Always permission unless needed.

mobileideafactory
  • 1,640
  • 1
  • 22
  • 30
  • 1
    It looks like it was not designed with your scenario in mind. But the documentation says that AlwaysAuthorization should be used only if the app really needs it, so they should support it. I think you should file a bug with Apple. Btw. there is another way to prompt the user to change the status, redirecting them to the app settings with UIApplication.sharedApplication().openURL(NSURL(string:UIApplicationOpenSettingsURLString)). In my case it only shows None and Always, but if you could force it to show all three options... – MirekE Aug 07 '14 at 18:12

2 Answers2

3

You are right, calling requestAlwaysAuthorization will not do anything if the user already granted 'when in use' permission. A workaround I used was to link the user to the settings screen and let them turn on the 'Always' setting themselves. Here are the steps to do that:

  1. Create a new key in your app-Info.plist called NSLocationAlwaysUsageDescription and enter some reasons as to why you need to request the always permission in the value field.

    info.plist file

  2. Link your user to your app's settings screen (more info here)

    NSURL *settings = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    if ([[UIApplication sharedApplication] canOpenURL:settings])
        [[UIApplication sharedApplication] openURL:settings];
    
  3. Once the user taps your link they will see this:

    Initial settings screen

    and when they click on Location, they will be able to see both While Using the App and Always settings to choose from:

    Location access settings screen

  4. Monitor authorization changes in your app by implementing the CLLocationManager delegate method locationManager:didChangeAuthorizationStatus:
Community
  • 1
  • 1
ken
  • 3,897
  • 3
  • 22
  • 28
  • I'm requesting authorization and not seeing a prompt. Have you run into this? http://stackoverflow.com/questions/26923409/requesting-in-use-authorization-shows-no-prompt – quantumpotato Nov 14 '14 at 05:43
  • I'm not sure if this is the cause but you should only request for one or the other, not both 'Always' and 'WhenInUse' – ken Nov 14 '14 at 05:50
  • Having the extra field in the Info.plist shoudln't hurt, right? I took out the extra prompt. – quantumpotato Nov 14 '14 at 05:52
  • Yes, you will need that extra field in Info.plist for my solution here to work. What I meant was choosing between the requestWhenInUseAuthorization and requestAlwaysAuthorization, and not both. – ken Nov 14 '14 at 05:54
3

I don't know about objective-c, but it works fine for me in swift and iOS 8.4. Make sure you provide both keys in your info.plist

NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
// iOS 11 and up will require this key instead of AlwaysUsageDescription
NSLocationAlwaysAndWhenInUsageDescription

Then just call

locationManager.requestAlwaysAuthorization() 

And make sure locationManager is an instance variable! A local variable will be ignored for some strange reason. Apple Documentation

Andy
  • 866
  • 9
  • 14
  • Documentation states "If the current authorization status is anything other than kCLAuthorizationStatusNotDetermined, this method does nothing and does not call the locationManager:didChangeAuthorizationStatus: method." So this is incorrect. – Paludis Sep 04 '17 at 03:10
  • Here is a link to the documentation on how to escalate the authorisation level. Note, the NSLocationAlwaysAndWhenInUsageDescription key doesn't exist before iOS 11 https://developer.apple.com/documentation/corelocation/choosing_the_authorization_level_for_location_services/request_always_authorization – Andy Sep 09 '17 at 14:19