1

With CLLocationManager I can use the following code to determine if I can access location services on the device. This is the master setting for all apps and can be turned on and off.

if (self.locationManager.locationServicesEnabled) {
    [self.locationManager startUpdatingLocation];
}

But a user can deny access to an individual app and in order to not execute the code to use the location manager I need to know if the user approved access to location services for this specific app. I saw that at one point there was a property called locationServicesApproved which appears it would indicate if the user approved access to location services in this app. But it was removed in 2008.

Source: http://trailsinthesand.com/apple-removes-notifications-from-iphone-sdk-beta-4/

It appears that there is no way to determine if the user approved access to location services but that seems to be a big hole in the SDK.

Is this feature in the SDK elsewhere? What can I do to determine if the user has approved access to location services for the current app?

Brennan
  • 11,546
  • 16
  • 64
  • 86
  • 1
    It appears that you must wait for locationManager:didFailWithError: to be called and the error code will point to values in CLError.h. Values are kCLErrorLocationUnknown, kCLErrorDenied, kCLErrorNetwork, and kCLErrorHeadingFailure. It appears that the second value is what I should check to see if the user denied access to location services. – Brennan Mar 13 '10 at 20:49
  • it's okay to answer your own question and accept your own answer (you don't get rep, but it will help people searching later anyway). Plus, then the question appears as answered in the list. – Jason Coco Mar 13 '10 at 21:56

3 Answers3

4

Taken from this SO answer: locationServicesEnabled test passes when they are disabled in viewDidLoad

The locationServicesEnabled class method only tests the global setting for Location Services. AFAIK, there's no way to test if your app has explicitly been denied. You'll have to wait for the location request to fail and use the CLLocationManagerDelegate method locationManager:didFailWithError: to do whatever you need. E.g.

- (void)locationManager: (CLLocationManager *)manager
       didFailWithError: (NSError *)error {

    NSString *errorString;
    [manager stopUpdatingLocation];
    NSLog(@"Error: %@",[error localizedDescription]);
    switch([error code]) {
        case kCLErrorDenied:
            //Access denied by user
            errorString = @"Access to Location Services denied by user";
            //Do something...
            break;
        case kCLErrorLocationUnknown:
            //Probably temporary...
            errorString = @"Location data unavailable";
            //Do something else...
            break;
        default:
            errorString = @"An unknown error has occurred";
            break;
        }
    }

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
    [alert show];
    [alert release];
}

See the documentation on the CLError constants in the CLLocationManager class reference for more options.

Community
  • 1
  • 1
testing
  • 19,681
  • 50
  • 236
  • 417
0

I answered my own question in the comment to the question above.

The answer (copied from the comment above):

It appears that you must wait for locationManager:didFailWithError: to be called and the error code will point to values in CLError.h. Values are kCLErrorLocationUnknown, kCLErrorDenied, kCLErrorNetwork, and kCLErrorHeadingFailure. It appears that the second value is what I should check to see if the user denied access to location services.

EmptyStack
  • 51,274
  • 23
  • 147
  • 178
Brennan
  • 11,546
  • 16
  • 64
  • 86
0

Since iOS 4.2, you can use the global method + (CLAuthorizationStatus)authorizationStatus from CLLocationManager :

if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
    //User denied access to location service for this app
}
Thomas Desert
  • 1,346
  • 3
  • 13
  • 28