allowsbackgroundlocationupdates ios background location

allowsbackgroundlocationupdates - ¿IOS activará la aplicación terminada si está registrada con la ubicación para UIBackgroundModes?



ios background fetch (3)

Parece que ha encontrado una solución viable y parece que usar el marco de cambios significativos le ahorraría algo de vida de la batería, siempre que sea lo suficientemente precisa para sus propósitos. Su solución también es beneficiosa porque le permite hacer malabarismos potencialmente más que el límite por aplicación de 20 regiones que se pueden monitorear simultáneamente, solo monitoreando aquellas regiones en las que esté más cerca.

Necesito una funcionalidad similar, pero no creo que el cambio significativo sea lo suficientemente preciso para mi aplicación, así que busqué un poco más y encontré lo siguiente.

Según la Guía de programación para el conocimiento de la ubicación , en "Monitoreo de regiones basadas en formas":

En iOS, las regiones asociadas con su aplicación se rastrean en todo momento, incluso cuando su aplicación no se está ejecutando. Si se cruza un límite de región mientras una aplicación no se está ejecutando, dicha aplicación se vuelve a iniciar en segundo plano para controlar el evento. De manera similar, si la aplicación se suspende cuando ocurre el evento, se reactiva y se le da un corto período de tiempo para manejar el evento.

Y también en "Manejo de eventos de cruce de límites para una región":

Cada vez que la ubicación actual del usuario cruza una región límite, el sistema genera un evento de región apropiado para su aplicación. Si su aplicación ya se está ejecutando, estos eventos van directamente a los delegados de cualquier objeto del administrador de ubicación actual. Si su aplicación no se está ejecutando, el sistema la inicia en segundo plano para que pueda responder. Las aplicaciones pueden implementar los siguientes métodos para manejar los cruces de límites:

locationManager: didEnterRegion:

locationManager: didExitRegion:

En mi caso, solo necesitaba enviar una notificación cuando se cruzó el límite, así que configuré mi AppDelegate para que se ajustara a CLLocationManagerDelegate, creé una propiedad locationManager y coloqué esto en mi archivo de implementación:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.locationManager.delegate = self; return YES; } - (CLLocationManager *)locationManager { if (!_locationManager) { _locationManager = [[CLLocationManager alloc] init]; _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; } return _locationManager; } - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { UILocalNotification *notification = [[UILocalNotification alloc] init]; notification.alertBody = NSLocalizedString(@"You crossed a boundary!", @"user crossed a boundary"); [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; }

Las pruebas muestran que esto funciona sin necesidad de configurar la clave de ubicación UIBackgroundModes. En este caso de uso, el sistema operativo maneja la supervisión de límites por usted y luego envía el evento a su aplicación el tiempo suficiente para procesarlo. Esto no ejecuta la aplicación, solo la ejecuta en segundo plano durante unos segundos para procesar el evento de límite, durante el cual solo puede realizar actividades relevantes. Espero que esto ayude a alguien más, también!

Sé que si una aplicación utiliza "El servicio de ubicación de cambio significativo", iOS lo activará si se entrega una actualización de ubicación, incluso si la aplicación finaliza.

No pude encontrar una respuesta clara sobre el caso si la aplicación está usando servicios de ubicación estándar y especifica la ubicación como la clave para UIBackgroundModes: ¿iOS también se activará para entregar la actualización incluso si está terminada? ¿O es necesario que la aplicación se ejecute en segundo plano para obtener la devolución de llamada de actualización de ubicación?

ACTUALIZACIÓN: En el momento en que preguntaba esto, no tenía tiempo para probarlo. Pero después de obtener una respuesta aquí, escribí este fragmento de código en el delegado de mi aplicación para ver si mi aplicación terminada se relanzará cuando se actualice la ubicación. Estoy mostrando una notificación UILocal cuando me notifiquen la actualización. Sin embargo, cuando terminé mi aplicación y luego cambié mi ubicación en la ciudad, la aplicación no se relanzó y no recibí ninguna actualización. ¿Puedes decirme qué es lo que estoy haciendo mal?

ACTUALIZACIÓN # 2: De acuerdo con los hallazgos finales en esta sección de Preguntas y Respuestas, no hay nada de malo en este código y es el comportamiento esperado de una aplicación que usa servicios de ubicación estándar, que no se reiniciará después de la terminación.

He agregado la ubicación como uno de los UIBackgroundModes en el archivo Info.plist.

Y esta es la ubicación relacionada con partes de mi delegado de aplicación:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [UIApplication sharedApplication].applicationIconBadgeNumber = 0; m_locManager = [[CLLocationManager alloc] init]; m_locManager.delegate = self; [m_locManager startUpdatingLocation]; return YES; } - (void)applicationDidEnterBackground:(UIApplication *)application { [m_locManager startUpdatingLocation]; } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog("%@", [NSString stringWithFormat:@"Background Fail %@", [error localizedDescription]]); } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { UILocalNotification * theNotification = [[UILocalNotification alloc] init]; theNotification.alertBody = [NSString stringWithFormat:@"Background location %.06f %.06f %@" , newLocation.coordinate.latitude, newLocation.coordinate.longitude, newLocation.timestamp]; theNotification.alertAction = @"Ok"; theNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1]; [[UIApplication sharedApplication] scheduleLocalNotification:theNotification]; }


Sí, se comportará de la misma manera, excepto que recibirá actualizaciones con más frecuencia (y, por lo tanto, consumirá más batería).

Fuente: Estados de aplicaciones y multitarea en la sección Seguimiento de la ubicación del usuario .

EDITAR Después de volver a leer, parece que el programa se activará de un estado suspendido pero no terminado . Aunque no creo que realmente necesites este modo de fondo. Está diseñado para aplicaciones que necesitan información de ubicación precisa (como navegación paso a paso). Consulte la sección en la Guía de programación de ubicaciones sobre la programación "basada en regiones". El ejemplo en sus comentarios se enumera como uno de los usos de esta aplicación.

EDITAR DE NUEVO Según la discusión en los comentarios, la solución final parece ser un cambio de ubicación significativo hasta que el usuario esté lo suficientemente cerca, y luego cambiar a un cambio de ubicación preciso (y esperar que la aplicación no finalice durante ese tiempo ^^ )


Una vez que eliminas la aplicación, las actualizaciones de ubicación se envían a la aplicación.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Debe recopilar las actualizaciones de ubicación dentro de este método de delegado buscando la clave de inicio como se muestra a continuación.

if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { //Code to handle the location update }

Espero que esto es lo que buscas. Sí, debe configurar la clave "Modos de fondo requeridos" con el valor "La aplicación se registra para las actualizaciones de ubicación" en plist.