110 votes

Comportement pour changement important emplacement API lorsque terminé/suspendue ?

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

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

Si ma compréhension est que si votre application se termine (et je suppose que si vous n'appelez pas stopMonitoringSignificantLocationchanges de applicationWillTerminate, vous obtenez réveillé avec un UIApplicationLaunchOptionsLocationkey paramètre d' application:didFinishLaunchingWithOptions. À ce stade, vous créez votre CLLocationManager, appel startMonitoringSignificantLocationchanges et de faire de votre arrière-plan de traitement pour un temps limité. Donc, je suis très bien avec ce peu.

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 pour didFinishLaunchingWithOptions dit:

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

Ce qui suggère que vous ne recevrez de cet appel lorsque votre application est lancée (en raison d'un changement de lieu) après que vous avez été licencié.

Toutefois, le paragraphe sur le Changement Significatif de Service dans l' Emplacement de Sensibilisation Guide de Programmation a ceci à dire:

Si vous laissez ce 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 arrive. Au réveil, votre application est en arrière-plan et une petite quantité de temps à traiter les données de localisation. Parce que votre application est en arrière-plan, il devrait faire un minimum de travail et d'éviter toutes les tâches (telles que l'interrogation de la réseau) qui pourrait l'empêcher de retour avant le temps imparti expire. Si elle ne le fait pas, votre l'application peut être résilié.

Cela donne à penser que vous êtes réveillé avec des données de localisation si votre application a été suspendue, mais ne parvient pas à parler de la façon dont vous êtes réveillé:

  • Le UIApplicationDelegate obtenir un rappel de me dire que je suis la reprise d'un état de suspension dans un arrière-plan de l'état?
  • Le lieu manager (qui a été lyophilisé lorsque l'application a été suspendue) commencez à recevoir locationManager:didUpdateToLocation:fromLocation rappels?
  • Dois-je tout simplement besoin de mettre en œuvre le code dans mon didUpdateToLocation message qui vérifie l'état de l'application et ne minime de traitement si en mode arrière-plan?

Dans le processus de l'écriture, je crois que je viens de répondre à ma propre question, mais il serait bon d'avoir ma compréhension de cette confirmée par quelqu'un de plus compétent.

82voto

RedBlueThing Points 21332

Depuis que j'ai posé cette question, j'ai fait un peu juste (surtout sur le train entre le domicile et le travail) et ont confirmé que le comportement de suspension apps est comme je le soupçonnais, à la fin de la question.

Voilà, votre application suspendue est réveillé, vous n'avez pas de recevoir des rappels sur votre délégué d'application, au lieu de cela vous recevez votre emplacement des mises à jour via votre CLLocationManagerDelegate. Vous pouvez détecter que vous êtes en cours d'exécution en arrière-fond par la vérification de la applicationState, et de faire quelques travaux pour le cas où vous êtes réveillé à partir d'un état de suspension de faire lieu de traitement.

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

Je suis venu à cette conclusion avec un emplacement de harnais de test que vous pouvez télécharger et essayer. C'est une jolie application simple qui vous permet de tourner sur des changements importants, et gps changement d'Api par le biais de l'INTERFACE utilisateur et d'enregistrer toutes les réponses que vous obtenez en retour.

N. B. Point six dans la réponse précédente n'est pas correct. Lyophilisé suspendu applications ne reçoivent CLLocationManagerDelegate rappels quand ils sont réveillés à partir d'un état suspendu.

26voto

Tegeril Points 3862

Ma compréhension est comme suit (je suis en train d'écrire une application qui s'appuie sur cette API, mais je n'ai pas terminé cette composante assez pour commencer à tester):

  1. Votre application est exécutée pour la première fois, vous vous inscrivez à startMonitoringSignificantLocationchanges, et de fournir une fonction de rappel. Pendant que votre application est en cours d'exécution, il fera appel de rappel à chaque fois qu'il reçoit un changement significatif.
  2. Si votre application est mise à l'arrière-plan, UIApplication recevrez applicationWillResignActive, suivie par applicationDidEnterBackground.
  3. Si votre demande est tué pendant qu'il est suspendu dans l'arrière-plan, vous ne serez pas averti; toutefois, si votre application est tué pendant qu'il est en cours d'exécution (au premier plan ou d'arrière-plan à ma connaissance), vous obtiendrez un moment avec applicationWillTerminate. Vous ne pouvez pas demander de fond moment à partir de cette fonction.
  4. En dépit d'être tué dans l'arrière-plan, l'OS va relancer votre application. Si votre application est tout simplement lancé par le système d'exploitation pour un changement, vous obtiendrez un appel à candidature didFinishLaunchingWithOptions:

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
    

    pour vous aider à déterminer si vous venez de rentrer d'un arrière-plan de changement d'emplacement.

  5. Si, au lieu de cela, vous avez été en cours d'exécution en arrière-plan, et votre application est manuellement relancé par l'utilisateur, vous recevrez un applicationWillEnterForeground suivie par applicationDidBecomeActive.
  6. Indépendamment de la façon dont c'est arrivé, lorsque votre application est relancée (sauf s'il était encore en cours d'exécution en arrière-plan comme un résultat d'une tâche en arrière-plan et cette tâche a commencé à surveiller les changements de), vous devez indiquer explicitement à startMonitoringSignificantLocationchanges à nouveau, car le rappel est plus attaché après "la lyophilisation." Et oui, vous avez juste besoin de mettre en œuvre le code dans didUpdateToLocation une fois que vous avez re-joint un emplacement gestionnaire de quelque sorte une fois, en revenant de l'état suspendu.

C'est ce que je vais avec mon code de développement. Comme je l'ai mentionné avant, je ne suis pas tout à fait prêt à le tester sur un appareil donc je ne peux pas dire si je l'ai interprété tout correctement, de sorte que les commentateurs, n'hésitez pas à me corriger (si j'ai beaucoup de lecture sur le sujet).

Oh, et si, par quelque coup de malchance, vous dégagez une application qui fait ce que je veux mine de le faire, je pourrais pleurer :)

Bonne chance!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X