'CLLocationManager startUpdatingLocation not calling locationManager:didUpdateLocations: or locationManager:didFailWithError:

I'm trying to use the CLLocationManager framework in my iOS project to access the user's location but when I call

[locationManager startUpdatingLocation]

neither locationManager:didUpdateLocations: or locationManager:didFailWithError: are getting called.

//myViewController.h
@interface myViewController : UITableViewController <CLLocationManagerDelegate>
@end

//myViewController.m
@implementation myViewController{
    CLLocationManager *locationManager;
}

//edit
- (void)viewDidLoad
{
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
}
//finish edit

-(void)getLocation
{
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [locationManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)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 didUpdateLocations:(NSArray *)locations
{
    CLLocation *newLocation = locations[[locations count] -1];
    CLLocation *currentLocation = newLocation;
    NSString *longitude = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
    NSString *latitude = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];

if (currentLocation != nil) {
   NSLog(@"latitude: %@", latitude);
   NSLog(@"longitude: @"%@", longitude);
}else {
    UIAlertView *errorAlert = [[UIAlertView alloc]
                               initWithTitle:@"Error" message:@"Failed to Get Your Location" 
                                                     delegate:nil 
                                            cancelButtonTitle:@"OK" 
                                            otherButtonTitles:nil];
    [errorAlert show];
}

}
@end

Neither delegate method is being called despite what it says in the documentation:

"This method returns immediately. Calling this method causes the location manager to obtain an initial location fix (which may take several seconds) and notify your delegate by calling its locationManager:didUpdateLocations: method [...] In addition to your delegate object implementing the locationManager:didUpdateLocations: method, it should also implement the locationManager:didFailWithError: method to respond to potential errors."

Don't know how to debug the issue.

Thanks,

JA



Solution 1:[1]

enter image description hereJust add this in info.plist

NSLocationAlwaysUsageDescription --- I need Location

NSLocationWhenInUseUsageDescription --- I need Location

privacy - location usage description --- I need Location

Note that "I need Location" should be changed to describe your actual app's designed usage. It is communicated to the end user in the authorization message. (thanks @devios1)

  locationManager = [[CLLocationManager alloc] init];
  locationManager.delegate=self;
  locationManager.desiredAccuracy=kCLLocationAccuracyBest;
  locationManager.distanceFilter=kCLDistanceFilterNone;
  [locationManager requestWhenInUseAuthorization];
  [locationManager startMonitoringSignificantLocationChanges];
  [locationManager startUpdatingLocation];

Now it will call your didUpdateToLocation definitely.

for more details click here

Solution 2:[2]

You strongly need to check that you initialize CLLocationManager on main thread. In other case you will not get updateLocation event.

I can't find such info in Apple docs but it works for me anyway.

Solution 3:[3]

Location Services work a bit differently starting in iOS 8.

Mainly, you need to add a key NSLocationWhenInUseUsageDescription to your Info.plist file, and add a description why your app need Location, such as "Location needed to ...".

Note that you might also have to check for iOS version. Only iOS 8 and up have the Location Manager listen to the requestWhenInUseAuthorization call.

The link below shows more details: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/

Good luck!

Solution 4:[4]

With iOS 8.0 you need to call -[CLLocationManager requestWhenInUseAuthorization ] or -[CLLocationManager requestAlwaysAuthorization] first so the user gets asked to give your app permission to use the location.

Solution 5:[5]

You need to add below things to your project,

  1. In plist of your project add these things:

    1. Key: NSLocationAlwaysUsageDescription Type:String
    2. Key: NSLocationWhenInUseUsageDescription Type:String
  2. In the .m file with [locationManager startUpdatingLocation] add this condition :

    if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
         [locationManager requestAlwaysAuthorization];`
    

Then only your CLLocationManager delegate methods will get called.

Solution 6:[6]

I think you should check this link.You are not retaining the location manager object when declaring.

please give property to you object @property(nonatomic, strong)

Why the CLLocationManager delegate is not getting called in iPhone SDK 4.0?

Solution 7:[7]

So if you are running in simulator don't forget to set location in simulator menu. It looks like if it is set to none nothing is called in delegate... I am not sure than if this can happen on real device too but probably it's simulator specific.

Solution 8:[8]

I had the following in my code base:

-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    if( status == kCLAuthorizationStatusAuthorizedAlways ) {
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.delegate = self;
        _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        _locationManager.distanceFilter = 200;
    }
}

Turns out that this was getting called in an infinite loop, because initializing a locationManager triggers this method for some reason? I had not realized that. I had put it there to catch when permissions were granted. Instead, I set up a location manager and started updating the location, but then this fired and replaced it with one that wasn't updating the location, and kept looping over and over.

Solution for me was just to add && !_locationManager to the if condition.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 malex
Solution 3 Emilio Barcelos
Solution 4 orkoden
Solution 5 Michaël Azevedo
Solution 6 Community
Solution 7 Renetik
Solution 8 Jake T.