when usage tutorial requestwheninuseauthorization manager example description corelocation iphone cllocationmanager

iphone - usage - ¿Por qué no se llama a mi delegado de CLLocationmanager?



location when in use usage description (5)

No obtengo ninguna devolución de llamada de ubicación en el sim ni en el dispositivo. Tengo este código siendo llamado:

- (void)startLocationCallbacks: (NSObject*) ignore { locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; locationManager.distanceFilter = MINIMUM_METERS; [locationManager startUpdatingLocation]; NSLog(@"[DEBUG] [locationManager startUpdatingLocation] (%@, %@)", locationManager, locationManager.delegate); }

y las declaraciones de registro en la parte superior de ambos

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

y

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

pero ninguna de las declaraciones de registro se llama. Las notificaciones de ubicación están habilitadas para mi aplicación (como se muestra en Configuración, además dije "permitir")

¿Cuáles son algunas razones posibles por las que no estoy recibiendo actualizaciones de ubicación?

Config / otra información:

  • He asignado locationManager y lo he guardado en una propiedad de retención.
  • He llamado startUpdatingLocation
  • Estoy usando 4.1 SDK
  • El problema está en Sim & iPod-touch (2ª generación) y iPhone-3, todos ejecutando 4.1
  • Las notificaciones de ubicación están permitidas en mi aplicación (tanto como se indica en Configuración y porque hice clic en "permitir" en la alerta).
  • He usado CLLocationManager con éxito anteriormente (en muchas aplicaciones de envío). Este es un verdadero tráiler para mí.

¡Gracias!


¡Uf! Ok, lo encontré.

Resulta que una de las formas de hacer que un CLLocationManager no CLLocationManager las devoluciones de llamadas de ubicación es hacer toda la configuración en el subproceso no principal. Cuando moví mi rutina de configuración a un performSelectorOnMainThread , todo funcionó exactamente como se esperaba.

¡Qué pesadilla!

Espero que esta respuesta ayude a otros ...

Edición / aclaración:

Originalmente, tuve algo como esto:

- (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]; }

Pero llamar a setupLocationManager en un hilo impidió las devoluciones de llamada. Así que mi solución fue mover la línea

[self setupLocationManager];

fuera del hilo y de nuevo en appDidFinishLaunchingWithOptions


En mi caso, se debió a que mi dispositivo no pudo determinar la ubicación; mientras permanecía en el interior, la señal de GPS no estaba disponible y el wi-fi también estaba desconectado, por lo que el administrador de la ubicación simplemente no podía recibir datos de ubicación y nunca se llamó al delegado.

Una vez que conecté el wi-fi funcionó (supongo que moverse al aire libre también debería hacer el truco en ese caso, pero a veces no es una forma muy conveniente :))


En realidad puedes ejecutarlo desde otro hilo también. De la documentación de Apple:

La configuración de su objeto de administrador de ubicación siempre debe ocurrir en un hilo con un bucle de ejecución activo, como el hilo principal de su aplicación.

Simplemente asegúrese de que su ciclo de ejecución se esté ejecutando en ese hilo y que se envíen los eventos CLLocationManager. Más sobre el ciclo de ejecución: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html


Para iOS 8

1) Coloqué estas líneas justo después de haber iniciado el administrador de ubicación.

if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { [self.locationManager requestAlwaysAuthorization]; }

2) Agregué NSLocationAlwaysUsageDescription al plist y lo puse en una cadena y agregué un mensaje. 3) En mi objetivo, hice clic en la pestaña Capacidades y luego activé los modos de fondo y verifiqué "Actualizaciones de ubicación" y "Utiliza accesorios Bluetooth LE"

Esto funciono para mi