Почему расположение [CLLocationManager] не обновляется при отправке сообщения CLLocationManagerDelegate?
Когда сообщение locationManager:didUpdateLocations:
(или его устаревший эквивалент locationManager:didUpdateToLocation:fromLocation:
) отправляется в CLLocationManagerDelegate
, Ссылка на протокол CLLocationManagerDelegate гласит:
Однако на практике СВОЙСТВОК тому времени, когда это сообщение будет доставлено вашему делегату, новый данные о местоположении также доступны непосредственно из CLLocationManager объект. Параметр newLocation может содержать данные, которые были кэшированы из предыдущего использования службы определения местоположения. Вы можете использовать свойство timestamp местоположения объект для определения того, насколько недавно данные о местоположении есть.
CLLocationManager
location
не обновляется. А почему бы и нет?
Я создал примерный проект, чтобы продемонстрировать это: https://github.com/sibljon/CoreLocationDidUpdateToLocationBug
Соответствующий код находится в JSViewController
, фрагмент которого приведен ниже:
- (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];
}
2 ответа:
Я считаю, что это ошибка, и я подал сообщение об ошибке в Apple. Зеркало отчета об ошибке можно найти на открытом радаре:
Как вы прочитали в документации, locationManagerDelegate может доставлять кэшированные данные в метод обратного вызова.
На самом деле это происходит довольно часто, поэтому вам нужно проверить метку времени
newLocation
противoldLocation
или текущего времени, чтобы увидеть, достаточно ли они отличаются (насколько отличаются, зависит от потребностей вашего приложения).Вот фрагмент того, как вы можете выполнить проверку по текущему времени:
if ([newLocation.timestamp timeIntervalSinceNow] < 600) // 10 minutes