Reputation: 8050
When the locationManager:didUpdateLocations:
(or its deprecated equivalent locationManager:didUpdateToLocation:fromLocation:
) message is sent to the CLLocationManagerDelegate
, the CLLocationManagerDelegate Protocol Reference states that:
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 the data that was cached from a previous usage of the location service. You can use the timestamp property of the location object to determine how recent the location data is.
However, in practice, CLLocationManager
's location
property is not updated. Why not?
I have created a sample project to demonstrate this: https://github.com/sibljon/CoreLocationDidUpdateToLocationBug
The relevant code is in JSViewController
, a snippet 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];
}
Upvotes: 5
Views: 1306
Reputation: 18670
As you have read in the documentation, the locationManagerDelegate might deliver cached data to the callback method.
This actually happens quite frequently so what you need to do is check the timestamp of the newLocation
against oldLocation
or current time, to see if they are different enough (how different is up to you to decide based on your app's needs).
Here's a snippet of how you could do the check against the current time:
if ([newLocation.timestamp timeIntervalSinceNow] < 600) // 10 minutes
Upvotes: 0
Reputation: 8050
I believe this to be a bug and I have filed a bug report with Apple. A mirror of the bug report can be found on Open Radar:
http://openradar.appspot.com/radar?id=2682402
Upvotes: 1