Comportement pour L'API d'emplacement de changement significatif lorsqu'elle est terminée / suspendue?

C'est la section de la documentation CLLocationManager décrivant le comportement de l'application avec startMonitoringSignificantLocationchanges:

Si vous démarrez ce service et l'application est par la suite terminé, le système automatiquement relance l'application dans le contexte si un nouvel événement arrive. Dans un tel cas, le dictionnaire des options passé à la application: didFinishLaunchingWithOptions: méthode de votre application délégué contient la clé UIApplicationLaunchOptionsLocationkey pour indiquer que votre demande était lancé en raison d'un événement de localisation. Sur la relance, vous devez toujours configurer un objet gestionnaire d'emplacement et appelez cette méthode pour continuer réception des événements de localisation. Lorsque vous redémarrez les services de localisation, le courant l'événement est livré à votre délégué immédiatement. En outre, l'emplacement propriété de votre gestionnaire de localisation objet est rempli avec le plus récent emplacement objet avant même que vous démarrer les services de localisation.

Donc, ma compréhension est que si votre application se termine (et je suppose que si vous n'appelez pas stopMonitoringSignificantLocationchanges de applicationWillTerminate ) vous serez réveillé avec unuiapplicationlaunchoptionslocationkey paramètre àapplication:didFinishLaunchingWithOptions . À ce stade, vous créez votre CLLocationManager , appelez startMonitoringSignificantLocationchanges et effectuez le traitement de votre emplacement d'arrière-plan pendant un Temps limité. Donc, je suis bien avec ce bit.

Le paragraphe précédent ne parle que de ce qui se passe lorsque l'application est terminée, il ne suggère pas ce que vous faites lorsque l'application est suspendue. La documentation de didFinishLaunchingWithOptions indique:

L'application suit l'emplacement mises à jour en arrière-plan, a été purgé, et a maintenant été relancer. Dans ce cas, le dictionnaire contient une clé indiquant que la demande était relancé en raison d'un nouvel emplacement événement.

Ce qui suggère que vous ne recevrez cet appel que lorsque votre application sera lancée (en raison d'un changement d'emplacement) après votre résiliation.

Cependant, le paragraphe du service de changement important dans le Guide de programmation de sensibilisation à L'emplacement {[2] } contient ce qui suit:

Si vous laissez ceci service en cours d'exécution et votre demande est ensuite suspendu ou résilié, le service réveille automatiquement votre application lorsque de nouvelles données de localisation arriver. Au réveil, votre l'application est mise en arrière plan et étant donné un peu de temps pour traiter les données de localisation. Parce votre application est en arrière-plan, il devrait faire un travail minimal et éviter toutes les tâches (telles que l'interrogation du réseau) qui pourrait l'empêcher de retour avant l'allocation temps expirer. Si elle ne le fait pas, votre l'application peut être résiliée.

Cela suggère que vous êtes réveillé avec des données de localisation si votre application a été suspendue, mais ne mentionne pas comment vous êtes réveillé:

  • Est-ce que le UIApplicationDelegate reçoit un rappel me disant que je recommence d'un état suspendu à un État d'arrière-plan?
  • le gestionnaire de localisation (qui a été lyophilisé lorsque l'application a été suspendue) commence-t-il à recevoir locationManager:didUpdateToLocation:fromLocation rappels?
  • ai-je juste besoin d'implémenter du code dans mon message didUpdateToLocation qui vérifie l'état de l'application et effectue un traitement minimal en mode arrière-plan?

En train d'écrire ceci, je pense que je viens peut-être de répondre à ma propre question, mais ce serait génial d'avoir ma compréhension de cela confirmée par quelqu'un de plus compétent.

107
demandé sur Honey 2010-08-06 09:37:49

3 réponses

Depuis que j'ai posé cette question, j'ai fait un peu de tests (principalement dans le train entre la maison et le travail) et j'ai confirmé que le comportement des applications suspendues est comme je le soupçonnais à la fin de la question.

C'est-à-dire que votre application suspendue est réveillée, vous ne recevez aucun rappel sur votre délégué d'application, vous recevez plutôt les mises à jour de votre emplacement via votre CLLocationManagerDelegate existant. Vous pouvez détecter que vous exécutez en arrière-plan en vérifiant le applicationState , et effectuez un travail limité dans le cas où vous êtes réveillé d'un état suspendu pour effectuer un traitement de localisation.

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

Je suis arrivé à cette conclusion avec un harnais de test de localisation que vous êtes invités à Télécharger et essayer. C'est une application assez simple qui vous permet d'activer les API de changement significatif et de changement GPS via L'interface utilisateur et de consigner toutes les réponses que vous obtenez.

N.B. le point six de la réponse précédente n'est pas correct. lyophilisé les applications suspendues reçoivent des rappels CLLocationManagerDelegate lorsqu'elles sont réveillées d'un état suspendu.

80
répondu RedBlueThing 2018-02-15 08:02:18

Ma compréhension est la suivante (je suis en train d'écrire une application qui repose sur cette API, mais qui n'a pas suffisamment terminé ce composant pour commencer à tester):

  1. votre application est exécutée pour la première fois, vous vous inscrivez à startMonitoringSignificantLocationchanges et fournissez une fonction de rappel. Pendant que votre application est en cours d'exécution, elle appellera ce rappel chaque fois qu'elle recevra un changement important.
  2. Si votre application est mise en arrière-plan, UIApplication recevra applicationWillResignActive , suivi de applicationDidEnterBackground.
  3. Si votre application est tuée alors qu'elle est suspendue en arrière-plan, vous ne serez pas averti; cependant, si votre application est tuée pendant qu'elle est en cours d'exécution (premier plan ou arrière-plan à ma connaissance), vous obtiendrez un moment avec applicationWillTerminate. Vous ne pouvez pas demander de temps d'arrière-plan supplémentaire à cette fonction.
  4. En dépit d'être tué dans le en arrière-plan, le système d'exploitation va relancer votre application. Si votre application est simplement lancée par le système d'exploitation pour un changement, vous recevrez un appel à application didFinishLaunchingWithOptions :

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
    

    Vous aidera à déterminer si vous êtes revenu d'un changement d'emplacement d'arrière-plan.

  5. si, à la place, vous étiez en cours d'exécution en arrière-plan et que votre application est relancée manuellement par l'utilisateur, vous recevrez applicationWillEnterForeground suivi de applicationDidBecomeActive .
  6. quelle que soit la façon dont cela s'est passé, lorsque votre application est relancée (à moins qu'elle ne s'exécute toujours en arrière-plan à la suite d'une tâche d'arrière-plan et que cette tâche ait commencé à surveiller les modifications), vous devez lui dire explicitement startMonitoringSignificantLocationchanges parce que le rappel n'est plus attaché"Et oui, vous avez juste besoin d'implémenter du code dans didUpdateToLocation une fois que vous avez ré-attaché un gestionnaire de localisation d'une sorte une fois revenu de l'état suspendu.

C'est ce que je fais avec mon développement de code en ce moment. Comme je l'ai mentionné précédemment, Je ne suis pas tout à fait prêt à tester cela sur un appareil, donc je ne peux pas dire si j'ai tout interprété correctement, alors les commentateurs, n'hésitez pas à me corriger (bien que j'ai fait une lecture substantielle sur le sujet).

Oh, et si par un coup de malchance, vous libérez une application qui fait ce que je veux que le mien fasse, je pourrais pleurer :)

Bonne chance!

25
répondu Aaron 2010-08-19 05:16:55

Si l'application est évoquée à partir de l'état suspendu à la suite d'un changement d'emplacement, l'application se lancera en arrière-plan.

Tous les objets seront en direct et vous recevrez la mise à jour de l'emplacement dans le délégué existant.

1
répondu Anshu 2015-01-28 10:29:02