iOS: App is not asking user's permission while installing the app. getting kCLAuthorizationStatusNotDetermined every time - Objective-c & Swift
iOS8 has got us major API changes with the LocationsServices
Assuming [CLLocationManager locationServicesEnabled]
return YES,
With the First Launch of the iOS App [both iOS7 and iOS8] - locationMangers(CLLocationManager) authorizationStatus preset to
authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined
Prompting in iOS7+
Initiate the locationManger (CLLocationManager, Strong) and set the delegates(CLLocationManagerDelegate)
Now to prompt the user to use Locations Services and List the App under the Settings> Privacy> Locations Services its MUST to call any of the Locations Services Methods, its depends on the App requirement- for example if app is kind of one of the below
Locations Updates - [self.locationManager startUpdatingLocation]
RegionMonitoring - [self.locationManager startMonitoringForRegion:beaconRegion]
right after executions of the above method iOS will prompt user requesting to accept use of Locations Services in app and irrespective of user choice app will be listed under the Settings > Privacy > Locations Services.
Prompting in iOS8+
Its in same case with iOS8, with the first launch the App Locations Services
authorizationStatus(CLAuthorizationStatus) = kCLAuthorizationStatusNotDetermined
iOS 8 we got new methods for showing prompt to user
[self.locationManager requestAlwaysAuthorization] or[self.locationManager requestWhenInUseAuthorization]
requestAlwaysAuthorization/requestWhenInUseAuthorization availbable from iOS8.if App deployment target is iOS7 then wrap this under if block to make sure in iOS7 this doesn't lead to app crash.
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){[self.locationManager requestAlwaysAuthorization]; .}
or
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){[self.locationManager requestWhenInUseAuthorization];}
Very Important ###:
As per iOS8 its mandatory to include the string stating why app uses requestAlwaysAuthorization/requestWhenInUseAuthorization In info.plist include any of these property respective to the requirement of the app
for kCLAuthorizationStatusAuthorizedAlways include Key/Value(string Value) pair
NSLocationAlwaysUsageDescription = App use Locations service mode Always
for kCLAuthorizationStatusAuthorizedWhenInUse include Key/Value(string Value) pair
NSLocationWhenInUseUsageDescription = App use Locations service mode In Use
Screenshot of info.plist (in case anybody is confused by this)
I was facing the same issue, after re-installing my app it was returning kCLAuthorizationStatusNotDetermined
whenever checking for [CLLocationManager authorizationStatus]
and the app didn't even show up in Settings > Privacy > Location Services.
The authorization dialog that iOS prompts user to approve access to location services is triggered on [locationManager startUpdatingLocation]
which in your case is never called (shouldFetchUserLocation
will be always NO
).
Miguel C.'s solution seems like a good fix, will try that.
Edit for iOS8.x
When iOS8 came it brought little change in the way CLLocationManager is used. As mentioned few times in other answers it requires additional step comparing to iOS7. Today I faced the issue myself and found this article (it's been referenced from multiple other questions but it completes my earlier answer). Hope it helps!
Objective-CFollow the below intructions:
iOS-11For iOS 11 have a look into this Answer: iOS 11 location access
Need to Add two Keys into plist and provide message as below image:
1. NSLocationAlwaysAndWhenInUseUsageDescription 2. NSLocationWhenInUseUsageDescription
NSLocationWhenInUseUsageDescription
locationManager = [[CLLocationManager alloc] init];locationManager.delegate = self;locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){ [locationManager requestWhenInUseAuthorization];}else{ [locationManager startUpdatingLocation];}
Delegat Methods
#pragma mark - Lolcation Update - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ NSLog(@"didFailWithError: %@", error); UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [errorAlert show];}-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{ switch (status) { case kCLAuthorizationStatusNotDetermined: case kCLAuthorizationStatusRestricted: case kCLAuthorizationStatusDenied: { // do some error handling } break; default:{ [locationManager startUpdatingLocation]; } break; }}- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ CLLocation *location = [locations lastObject]; userLatitude = [NSString stringWithFormat:@"%f", location.coordinate.latitude] ; userLongitude = [NSString stringWithFormat:@"%f",location.coordinate.longitude]; [locationManager stopUpdatingLocation];}
Swift Code
Follow the below instructions:
iOS-11For iOS 11 have a look into this Answer: iOS 11 location access
Need to Add two Keys into plist and provide message as below image:
1. NSLocationAlwaysAndWhenInUseUsageDescription 2. NSLocationWhenInUseUsageDescription
import CoreLocationclass ViewController: UIViewController ,CLLocationManagerDelegate {var locationManager = CLLocationManager()//MARK- Update Location func updateMyLocation(){ locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers; if locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)){ locationManager.requestWhenInUseAuthorization() } else{ locationManager.startUpdatingLocation() }}
Delegate Methods
//MARK: Location Updatefunc locationManager(manager: CLLocationManager, didFailWithError error: NSError) { NSLog("Error to update location :%@",error)}func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { switch status { case .NotDetermined: break case .Restricted: break case .Denied: NSLog("do some error handling") break default: locationManager.startUpdatingLocation() }}func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last! as CLLocation var latitude = location.coordinate.latitude var longitude = location.coordinate.longitude}