Comportamiento para la API de ubicación de cambio significativo cuando se termina / suspende?


Esta es la sección de la documentación de CLLocationManager que describe el comportamiento de la aplicación con startMonitoringSignificantLocationChanges :

Si inicia este servicio y su la solicitud es posterior terminado, el sistema automáticamente relanza la aplicación en el fondo si llega un nuevo evento. En tal caso, el diccionario de opciones pasado a la aplicación:didFinishLaunchingWithOptions: método de su solicitud delegado contiene la clave Uiaplicacióncopcionesclocación Clave para indicar que su solicitud fue lanzado debido a un evento de ubicación. Al relanzar, usted debe todavía configurar un objeto de administrador de ubicación y llame a este método para continuar recepción de eventos de ubicación. Cuando servicios de ubicación de reinicio, el actual el evento se entrega a su delegado inmediatamente. Además, la ubicación propiedad de su gerente de ubicación objeto se rellena con la mayoría reciente ubicación del objeto incluso antes que usted servicios de ubicación de inicio.

Así que entiendo que si su aplicación termina (y asumo que si no llama a stopMonitoringSignificantLocationChanges desde applicationWillTerminate) se despertará con un parámetro Uiapplicationlaunchoptionsslocationkey a application:didFinishLaunchingWithOptions. En ese momento crea su CLLocationManager , llame startMonitoringSignificantLocationChangesy hacer su procesamiento de ubicación en segundo plano por un tiempo limitado. Así que estoy bien con esta parte.

El párrafo anterior solo habla de lo que sucede cuando se termina la aplicación, no sugiere lo que haces cuando se suspende la aplicación. La documentación para didFinishLaunchingWithOptions dice:

La aplicación rastrea la ubicación actualizaciones en segundo plano, fue purgado, y ahora ha sido relanzar. En este caso, el diccionario contiene una clave indicating that the application was relanzado debido a una nueva ubicación evento.

Sugiriendo que solo recibirá esta llamada cuando se inicie su aplicación (debido a un cambio de ubicación) después de que haya finalizado.

Sin embargo, el párrafo sobre el Servicio de Cambio Significativo en la Guía de Programación de Conocimiento de Ubicación tiene lo siguiente que decir:

Si dejas esto servicio de ejecución y su solicitud es posteriormente suspendido o terminado, el servicio automáticamente despierta su aplicación cuando nuevos datos de ubicación llegar. A la hora de despertar, su la aplicación se pone en segundo plano y dado una pequeña cantidad de tiempo para procesar los datos de ubicación. Porque su aplicación está en segundo plano, debe hacer un trabajo mínimo y evitar cualquier tarea (como consultar el red) que podrían impedir que volver antes de la asignación tiempo expirar. Si no lo hace, su la solicitud puede darse por terminada.

Esto sugiere que se le despierta con datos de ubicación si su aplicación ha sido suspendida, pero no menciona cómo se le despierta:

  • ¿El UIApplicationDelegate recibe una devolución de llamada que me dice que estoy reanudando de un estado suspendido a un estado de fondo?
  • El administrador de ubicación (que se congeló cuando se suspendió la aplicación) comienza a recibir LocationManager: didUpdateToLocation: fromLocation callbacks?
  • ¿Solo necesito implementar código en mi mensaje didUpdateToLocation que comprueba el estado de la aplicación y hace un procesamiento mínimo si está en modo de fondo?

En el proceso de escribir esto, creo que acabo de responder a mi propia pregunta, pero sería genial tener mi comprensión de esto confirmada por alguien más conocedor.

Author: Honey, 2010-08-06

3 answers

Desde que hice esta pregunta, he hecho un poco de pruebas (sobre todo en el tren entre casa y trabajo) y he confirmado que el comportamiento de las aplicaciones suspendidas es como sospechaba al final de la pregunta.

Es decir, su aplicación suspendida se despierta, no recibe ninguna devolución de llamada en su delegado de aplicación, en su lugar, recibe sus actualizaciones de ubicación a través de su existente CLLocationManagerDelegate. Puede detectar que se está ejecutando en segundo plano comprobando el applicationState, y hacer un trabajo limitado para el caso en el que se despierta de un estado suspendido para hacer el procesamiento de ubicación.

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

Llegué a esta conclusión con un arnés de prueba de ubicación que puede descargar y probar. Es una aplicación bastante simple que le permite activar cambios significativos y API de cambio de GPS a través de la interfaz de usuario y registrar todas las respuestas que obtenga.

N.B. El punto seis de la respuesta anterior no es correcto. Liofilizado aplicaciones suspendidas reciben CLLocationManagerDelegate devoluciones de llamada cuando se despiertan de un estado suspendido.

 80
Author: RedBlueThing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-15 08:02:18

Mi comprensión es la siguiente (estoy en el proceso de escribir una aplicación que se basa en esta API, pero no he completado este componente lo suficiente como para comenzar a probar):

  1. Su aplicación se ejecuta por primera vez, se registra en startMonitoringSignificantLocationChanges y proporciona una función de devolución de llamada. Mientras su aplicación se está ejecutando, llamará a esa devolución de llamada cada vez que reciba un cambio significativo.
  2. Si su solicitud se pone en segundo plano, UIApplication recibirá applicationWillResignActive, seguido de applicationDidEnterBackground.
  3. Si su aplicación se mata mientras está suspendida en segundo plano, no se le notificará; sin embargo, si su aplicación se mata mientras se está ejecutando (en primer plano o en segundo plano que yo sepa), obtendrá un momento con applicationWillTerminate. No puede solicitar tiempo de fondo adicional de esta función.
  4. A pesar de ser asesinado en el en segundo plano, el sistema operativo reiniciará su aplicación. Si su aplicación es simplemente lanzada por el sistema operativo para un cambio, recibirá una llamada a application didFinishLaunchingWithOptions :

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
    

    Le ayudará a determinar si ha regresado de un cambio de ubicación en segundo plano.

  5. Si, en cambio, se estaba ejecutando actualmente en segundo plano, y su aplicación es relanzada manualmente por el usuario, recibirá un applicationWillEnterForeground seguido de applicationDidBecomeActive.
  6. Independientemente de cómo sucedió, cuando su aplicación se relanza (a menos que todavía se esté ejecutando en segundo plano como resultado de una tarea en segundo plano y dicha tarea haya comenzado a monitorear los cambios), debe indicarle explícitamente a startMonitoringSignificantLocationChanges de nuevo porque la devolución de llamada ya no se adjunta después de "liofilización"."Y sí, solo necesitas implementar código en didUpdateToLocation una vez que hayas vuelto a adjuntar un manejador de ubicación de algún tipo una vez que regrese del estado suspendido.

Esto es lo que estoy haciendo con mi desarrollo de código en este momento. Como mencioné antes, no estoy listo para probar esto en un dispositivo, así que no puedo decir si he interpretado todo correctamente, así que los comentaristas, por favor, siéntanse libres de corregirme (aunque he hecho una lectura sustancial sobre el tema).

Oh, y si por algún golpe de mala suerte, lanzas una aplicación que hace lo que quiero que la mía haga, podría llorar :)

¡Buena suerte!

 25
Author: Aaron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-19 05:16:55

Si la aplicación se evoca desde el estado suspendido como resultado del cambio de ubicación, la aplicación se iniciará en estado de fondo.

Todos los objetos estarán en vivo y recibirá una actualización de ubicación en el delegado existente.

 1
Author: Anshu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-28 10:29:02