Why is [CLLocationManager location] not updated when sending a CLLocationManagerDelegate message?

When a message locationManager:didUpdateLocations:(or its obsolete equivalent locationManager:didUpdateToLocation:fromLocation:) is sent to CLLocationManagerDelegate, Link to CLLocationManagerDelegate Protocol), specify:

By the time this message is delivered to your delegate, the new location data is also available directly from the CLLocationManager object. The newLocation parameter may contain data that has been cached from previous use of the location service. You can use the timestamp property of a location object to determine how recently location data is.

However, in practice, the property is CLLocationManager locationnot updated. Why not?

I created a sample project to demonstrate this: https://github.com/sibljon/CoreLocationDidUpdateToLocationBug

The corresponding code is in JSViewController, a fragment of which is below:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    self.locationManager.distanceFilter = 10000.0; // 10 km
    self.locationManager.delegate = self;
    self.locationManager.purpose = @"To show you nearby hotels.";
    [self.locationManager startUpdatingLocation];

    [self.locationManager startUpdatingLocation];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appWillEnterForeground:)
                                                 name:UIApplicationWillEnterForegroundNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appDidEnterBackground:)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"New location: %@", newLocation);
    NSLog(@"Old location: %@", oldLocation);
    NSLog(@"- [CLLocationManager location]: %@", manager.location);
}

//- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
//{
//    for (CLLocation *location in locations)
//    {
//        NSLog(@"Current location: %@", locations);
//    }
//    NSLog(@"- [CLLocationManager location]: %@", manager.location);
//}

#pragma mark - Notifications

- (void)appWillEnterForeground:(NSNotification *)notification
{
    [self.locationManager startUpdatingLocation];
}

- (void)appDidEnterBackground:(NSNotification *)notification
{
    [self.locationManager stopUpdatingLocation];
}
+5
source share
2 answers

I believe this is a bug, and I posted a bug report with Apple. The error report mirror can be found in Open Radar:

http://openradar.appspot.com/radar?id=2682402

+1
source

As you read in the documentation, locationManagerDelegate can deliver cached data to the callback method.

This happens quite often, so you need to check the timestamp newLocationfor oldLocationor the current time to see if they are different enough (how different your decisions are based on your application).

, :

    if ([newLocation.timestamp timeIntervalSinceNow] < 600) // 10 minutes
0

All Articles