Comportamiento para una API de location de cambio significativa cuando se termina / suspende?

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

Si inicia este service y su aplicación finaliza posteriormente, el sistema automáticamente relanza la aplicación en segundo plano si llega un nuevo evento. En tal caso, el dictionary de opciones pasó a la aplicación: didFinishLaunchingWithOptions: método de su delegado de aplicación contiene la key UIApplicationLaunchOptionsLocationKey para indicar que su aplicación se lanzó debido a un evento de location. Al relanzar, debe configurar un object de administrador de location y llamar a este método para continuar recibiendo events de location. Cuando reinicia los services de location, el evento actual se entrega a su delegado de inmediato. Además, la propiedad de location de su object de administrador de location se rellena con el object de location más reciente incluso antes de iniciar los services de location.

Entonces entiendo que si su aplicación termina (y supongo que si no llama a stopMonitoringSignificantLocationChanges desde applicationWillTerminate ), se despertará con un parámetro UIApplicationLaunchOptionsLocationKey a la aplicación: didFinishLaunchingWithOptions . En ese punto, crea tu CLLocationManager , llama a startMonitoringSignificantLocationChanges y realiza el procesamiento de la location en segundo plano por un time limitado . Entonces estoy bien con esta parte.

El párrafo anterior solo habla sobre lo que sucede cuando la aplicación termina, no sugiere qué hacer cuando se suspende la aplicación. La documentation de didFinishLaunchingWithOptions dice:

La aplicación rastrea actualizaciones de location en segundo plano, se purgó y ahora ha sido relanzada. En este caso, el dictionary contiene una key que indica que la aplicación se relanzó debido a un nuevo evento de location.

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

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

Si deja este service en ejecución y su aplicación se suspende o termina posteriormente, el service automáticamente despierta su aplicación cuando llegan nuevos datos de location. En el momento de la activación, su aplicación se pone en segundo plano y se le da una pequeña cantidad de time para procesar los datos de location. Debido a que su aplicación está en segundo plano, debería hacer un trabajo mínimo y evitar cualquier tarea (como consultar la networking) que podría evitar que regrese antes de que expire el time asignado. De lo contrario, su request puede darse por terminada.

Esto sugiere que te despiertan con datos de location si tu aplicación ha sido suspendida, pero no menciona cómo te despiertan:

  • ¿El UIApplicationDelegate recibe una callback que me dice que estoy reanudando de un estado suspendido a un estado de background?
  • ¿El administrador de la location (que estaba liofilizado cuando la aplicación fue suspendida) comenzó a recibir el gestor de location: didUpdateToLocation: de las devoluciones de llamada de la location ?
  • ¿Solo necesito implementar código en mi post didUpdateToLocation que verifica el estado de la aplicación y realiza un procesamiento mínimo si está en modo de background?

En el process de escribir esto, creo que quizás haya respondido a mi propia pregunta, pero sería genial que mi entendimiento de esto haya sido confirmado por alguien más informado.

Desde que hice esta pregunta, he hecho algunas testings (sobre todo en el tren entre el hogar y el trabajo) y he confirmado que el comportamiento de las aplicaciones suspendidas es lo que sospeché al final de la pregunta.

Es decir, su aplicación suspendida se reactiva, no recibe ninguna callback en su delegado de la aplicación, sino que recibe sus actualizaciones de location a través de su CLLocationManagerDelegate existente. Puede detectar que está ejecutando el background comprobando el estado de la aplicación y realizando un trabajo limitado para el caso en el que se despierta de un estado suspendido para realizar el procesamiento de la location.

[UIApplication shanetworkingApplication].applicationState == UIApplicationStateBackground 

Llegué a esta conclusión con un arnés de testing de location que puede download y probar. Es una aplicación bastante simple que le permite activar cambios significativos y gps cambiar API a través de la interfaz de usuario y registrar todas las respuestas que regrese.

NB El punto seis en la respuesta anterior no es correcto. Las aplicaciones suspendidas liofilizadas reciben llamadas de devolución CLLocationManagerDelegate cuando se retiran de un estado suspendido.

Mi entendimiento es el siguiente (estoy en el process de escribir una aplicación que depende de 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 para iniciarMonitoringSignificantLocationChanges y proporciona una function de callback. Mientras se ejecuta su aplicación, llamará a esa callback cada vez que reciba un cambio significativo.
  2. Si su aplicación se coloca 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 tu aplicación se mata mientras se está ejecutando (primer plano o background que yo sepa), obtendrás un momento con applicationWillTerminate . No puede solicitar time adicional de background de esta function.
  4. A pesar de ser asesinado en segundo plano, el SO reiniciará su aplicación. Si su aplicación es simplemente lanzada por el sistema operativo para un cambio, recibirá una llamada a la aplicación didFinishLaunchingWithOptions :

     if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) 

    lo ayudará a determinar si ha vuelto de un cambio de location de background.

  5. Si, en cambio, se estaba ejecutando actualmente en segundo plano, y su aplicación es relanzada manualmente por el usuario, recibirá una aplicación WillEnterForeground seguida de applicationDidBecomeActive .
  6. Independientemente de cómo sucedió, cuando se reanuda su aplicación (a less que todavía se esté ejecutando en segundo plano como resultado de una tarea de background y dicha tarea haya comenzado a supervisar los cambios), debe decirle explícitamente que inicieMonitoringSignificantLocationChanges nuevamente porque la callback no es más time conectado después de "liofilización". Y sí, solo necesita implementar código en didUpdateToLocation una vez que haya vuelto a adjuntar un controller de location de algún tipo una vez que regrese del estado suspendido.

Esto es lo que estoy haciendo ahora con mi desarrollo de código. Como mencioné antes, no estoy preparado para probar esto en un dispositivo, así que no puedo decir si lo he interpretado correctamente, por lo que los comentaristas, por favor, no dude en corregirme (aunque he leído mucho sobre el tema).

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

¡Buena suerte!

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

Todos los objects estarán en vivo y recibirá la actualización de location en el delegado existente.