0

During requesting for Always permission on iOS13, the user can tap "Allow Once" which will call appropriate delegate with status kCLAuthorizationStatusAuthorizedWhenInUse but requesting for "Always" again calls delegate with kCLAuthorizationStatusAuthorizedAlways. Why? When other combinations work only once like you request always, you get it and even calling again will not call delegate with status.

Sample code to test:

@import CoreLocation;

@interface ViewController () <CLLocationManagerDelegate>

@property (strong, nonatomic) CLLocationManager *locationManager;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
}
- (IBAction)doauthloc:(id)sender {
    [self.locationManager requestAlwaysAuthorization];
}

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    switch(status) {
        case kCLAuthorizationStatusNotDetermined:NSLog(@"AUTH STATUS:kCLAuthorizationStatusNotDetermined"); break;
        case kCLAuthorizationStatusRestricted:NSLog(@"AUTH STATUS:kCLAuthorizationStatusRestricted"); break;
        case kCLAuthorizationStatusDenied:NSLog(@"AUTH STATUS:kCLAuthorizationStatusDenied"); break;
        case kCLAuthorizationStatusAuthorizedAlways:NSLog(@"AUTH STATUS:kCLAuthorizationStatusAuthorizedAlways"); break;
        case kCLAuthorizationStatusAuthorizedWhenInUse:NSLog(@"AUTH STATUS:kCLAuthorizationStatusAuthorizedWhenInUse"); break;
    };
}

@end
David Chelidze
  • 1,143
  • 12
  • 19

1 Answers1

5

It's a little confusing, isn't it? When you ask for Always and the user taps Allow Once, you are told that you got WhenInUse. But that doesn't actually matter. You have provisional Always. So:

  • When you subsequently go into the background and start monitoring visits or regions or whatever your location monitoring usage is, this will be converted into Always authorization for purposes of usage. (Your logging should confirm this.)

  • And then, because you got only Once authorization, when you come back to the foreground you will be Not Determined again.

So the takeaway is, just laugh an evil laugh and move on. Your background location monitoring will work, and that's all that matters. Not only does it work, but as a bonus you get to present the user with the authorization alert again, which is the reason for all this change in iOS 13. Don't worry, be happy.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Personally I think this revision in how alerts to the user work in iOS 13 for location authorization is totally awesome. It maximizes your chances of being able to do location services without surprising or annoying the user. (The only bad thing is the wording of the Always confirmation dialog when you come back to the front if the user tapped While Using when you requested Always; it's ungrammatical and incomprehensible.) – matt Oct 18 '19 at 17:05
  • 1
    Also I should note that what you are doing is not what you are expected to do. You are expected to ask for WhenInUse initially to show the dialog, and then ask for Always just as you go into the background and start using Always powers. – matt Oct 18 '19 at 17:08
  • I think it hasn't been stressed enough - to have the "always" location permissions *not having to pick "Once" on every app launch* you should first ask for `WhenInUse`, and afterwards - ask for `Always`. Two popups needed. – Kowboj Jul 26 '23 at 14:17