Почему мой делегат CLLocationmanager не получает вызов?
Я не получаю никаких обратных вызовов на любом сим или устройстве. Я получил этот код:
- (void)startLocationCallbacks: (NSObject*) ignore
{
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.distanceFilter = MINIMUM_METERS;
[locationManager startUpdatingLocation];
NSLog(@"[DEBUG] [locationManager startUpdatingLocation] (%@, %@)", locationManager, locationManager.delegate);
}
и операторы журнала в верхней части обеих
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
и
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
но ни один из операторов журнала не вызван. Уведомления о местоположении включены для моего приложения (как показано в разделе "Настройки", а также "Разрешить" ).
Каковы возможные причины, по которым я не получаю обновления местоположения?
Конфигурация/другая информация:
- Я выделил locationManager и сохранил его в свойстве сохранения.
- Я вызвал startUpdatingLocation
- Я использую 4.1 SDK
- Проблема заключается в Sim и iPod touch (2-го поколения) и iPhone-3, все работает 4.1
- Уведомления о местоположении разрешены в моем приложении (оба указаны в разделе "Настройки" и потому, что я нажал "разрешить" в уведомлении.)
- Я успешно использовал CLLocationManager (во многих приложениях для доставки!). Это настоящий прически для меня.
Спасибо!
Ответы
Ответ 1
Уф! Хорошо, я нашел его.
Оказывается, один из способов сделать CLLocationManager
не срабатывать обратные вызовы местоположения - это сделать всю настройку в не-главном потоке. Когда я перевел мою процедуру установки на performSelectorOnMainThread
, все работало точно так, как ожидалось.
Какой кошмар!
Надеюсь, этот ответ поможет другим...
Редактировать/уточнение:
Первоначально у меня было что-то вроде этого:
- (BOOL) appDidFinishLaunchingWithOptions: (NSDictionary*) options
{
// ...[app setup, snip]
[NSThread detachNewThreadSelector: @selector(postLaunchSetupThread) toTarget: self withObject: nil];
}
- (void)postLaunchSetupThread
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
// ...[other setup, snip]
[self setupLocationManager];
[pool release];
}
- (void)setupLocationManager
{
self.myLocationManager = [[[CLLocationManager alloc] init] autorelease];
[myLocationManager startLocationUpdates];
}
Но вызов setupLocationManager
в потоке предотвратил обратные вызовы. Так что я решил переместить строку
[self setupLocationManager];
из нити и обратно в appDidFinishLaunchingWithOptions
Ответ 2
На самом деле вы можете запустить его и из другого потока.
Из документации Apple:
Конфигурация вашего объекта менеджера местоположений всегда должна выполняться на поток с активным циклом запуска, например, ваши основные приложения нить.
Просто убедитесь, что в этом потоке запущен цикл выполнения, и отправляются события CLLocationManager.
Подробнее о запуске цикла:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html
Ответ 3
Для iOS 8
1) Я разместил эти строки сразу после запуска менеджера местоположений.
if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
2) Я добавил NSLocationAlwaysUsageDescription в plist и установил его в строку и добавил сообщение.
3) В моей цели я нажал вкладку "Возможности", а затем включил "Фоновые режимы" и установил флажок "Обновления местоположения" и "Использует аксессуары Bluetooth LE".
Это сработало для меня
Ответ 4
//проверить это
//...CLLocationManager не вызывает метод делегата правильно
//... после серии R & D Я использую метод сторожевого таймера, который он вызывает "
fooobar.com/questions/255506/...
Ответ 5
В моем случае это было из-за того, что мое устройство не смогло определить местоположение - в то время как пребывание в помещении GPS-сигнал был недоступен, а Wi-Fi также был отключен, поэтому менеджер местоположений просто не смог получить данные о местоположении, и делегат никогда не вызывался,
Как только я подключился к Wi-Fi, это сработало (я думаю, что перемещение на открытом воздухе должно также делать трюк в этом случае, но иногда это не очень удобно:))