My app that worked fine on iOS 7 doesn\'t work with the iOS 8 SDK.
CLLocationManager doesn\'t return a location, and I don\'t see my app under
Solution with backward compatibility:
SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
[self.locationManager respondsToSelector:requestSelector]) {
[self.locationManager performSelector:requestSelector withObject:NULL];
} else {
[self.locationManager startUpdatingLocation];
}
Setup NSLocationWhenInUseUsageDescription key in your Info.plist
Objective-C Procedure Follow the below instructions:
For iOS-11 For iOS 11 have a look at this Answer: iOS 11 location access
Need to Add two Keys into plist and provide message as below image:
1. NSLocationAlwaysAndWhenInUseUsageDescription
2. NSLocationWhenInUseUsageDescription
3. NSLocationAlwaysUsageDescription
For iOS-10 and below:
NSLocationWhenInUseUsageDescription
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
[locationManager requestWhenInUseAuthorization];
}else{
[locationManager startUpdatingLocation];
}
Delegate 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 Procedure
Follow the below instructions:
For iOS-11 For iOS 11 have a look at this Answer: iOS 11 location access
Need to Add two Keys into plist and provide message as below image:
1. NSLocationAlwaysAndWhenInUseUsageDescription
2. NSLocationWhenInUseUsageDescription
3. NSLocationAlwaysUsageDescription
For iOS-10 and below:
import CoreLocation
class 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 Update
func 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
}
Add key NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription (background GPS use) with string asking to use GPS on each info.plist from each target.
Ask for permission by running:
[self initLocationManager:locationManager];
Where initLocationManager is:
// asks for GPS authorization on iOS 8
-(void) initLocationManager:(CLLocationManager *) locationManager{
locationManager = [[CLLocationManager alloc]init];
if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
[locationManager requestAlwaysAuthorization];
}
Remember that if the keys are not on each info.plist for each target the app will not ask the user. The if provides compatibility with iOS 7 and the respondsToSelector: method guarantees future compatibility rather than just solving the issue for iOS 7 and 8.
I was working on an app that was upgraded to iOS 8 and location services stopped working. You'll probably get and error in the Debug area like so:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
I did the least intrusive procedure. First add NSLocationAlwaysUsageDescription entry to your info.plist:

Notice I didn't fill out the value for this key. This still works, and I'm not concerned because this is a in house app. Also, there is already a title asking to use location services, so I didn't want to do anything redundant.
Next I created a conditional for iOS 8:
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[_locationManager requestAlwaysAuthorization];
}
After this the locationManager:didChangeAuthorizationStatus: method is call:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus: (CLAuthorizationStatus)status
{
[self gotoCurrenLocation];
}
And now everything works fine. As always, check out the documentation.
// ** Don't forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
// Location Manager Delegate Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"%@", [locations lastObject]);
}
I add those key in InfoPlist.strings in iOS 8.4, iPad mini 2. It works too. I don't set any key, like NSLocationWhenInUseUsageDescription, in my Info.plist.
InfoPlist.strings:
"NSLocationWhenInUseUsageDescription" = "I need GPS information....";
Base on this thread, it said, as in iOS 7, can be localized in the InfoPlist.strings. In my test, those keys can be configured directly in the file InfoPlist.strings.
So the first thing you need to do is to add one or both of the > following keys to your Info.plist file:
- NSLocationWhenInUseUsageDescription
- NSLocationAlwaysUsageDescription
Both of these keys take a string which is a description of why you need location services. You can enter a string like “Location is required to find out where you are” which, as in iOS 7, can be localized in the InfoPlist.strings file.
UPDATE:
I think @IOS's method is better. Add key to Info.plist with empty value and add localized strings to InfoPlist.strings.