locationManager didFailWithError-
Hello,
Mon appli est à 80% basée sur les données en provenance du GPS de l'iPhone (pour affichage d'altitude GPS, de vitesse sol, de route sol). Il me faut donc impérativement avertir l'utilisateur en cas de soucis GPS, et en particulier en cas de mode Avion.
Je crois comprendre qu'il n'existe aucune solution directe pour savoir si le mode avion est sélectionné. J'ai donc implémenté la méthode didFailWithError. Quand elle est appelée, je lève un flag. Si le flag est levé, le ViewController avertit l'utilisateur : alert, affichage de caractères "?" en rouge sur mon appli en lieu et place de la vitesse et altitude normalement affichées, etc.
Si didUpdateLocations est appelée de nouveau, j'efface le flag et l'affichage revient à la normale.
Mon soucis :
- si je lance l'appli sans le mode avion, elle fonctionne, tout va bien
- si je lance l'appli en ayant auparavant sélectionné le mode avion, didFailWithError est appelée une fois, le problème est correctement traité et l'affichage revient à la normale si on enlève le mode avion
- si je lance l'appli sans mode avion, et qu'en cours d'utilisation on active ce mode avion, alors là c'est du grand n'importe quoi :
- didFailWithError n'est pas systématiquement appelée, auquel cas les données affichées n'ont plus de sens et l'utilisateur n'est pas prévenu du problème
- didUpdateLocations est parfois appelée alors que le mode avion est activé. Si didFailWithError avait bien été appelée auparavant et donc l'utilisateur avait été averti du soucis, mon appli considère alors que le GPS tourne et revient donc à un affichage normal
J'aimerai comprendre la logique de l'appel de cette méthode didFailWithError. Y a t'il un meilleur moyen pour surveiller le mode avion ?
Merci pour votre aide !!
Réponses
La NSError est toujours la même ?
Les données sont-elles totalement incorrectes ? Auquel cas tu pourrais peut-être les remarquer et les traiter.
Effectivement la NSError est toujours la même :
errorError Domain=kCLErrorDomain Code=0 "The operation couldn't be completed. (kCLErrorDomain error 0.)
didUpdateLocations est appelé à chaque changement de position mesuré.
Quand je passe en mode avion, didFailWithError est appelé une fois (parfois, pas toujours), et le délai entre l'entrée en mode avion et l'appel de cette méthode est très aléatoire, jusqu'à plusieurs minutes.
Après l'appel de didFailWithError, il arrive parfois, mais pas toujours, que didUpdateLocations soit de nouveau appelée. Et les données qui y sont récupérées ne sont pas totalement aberrantes. J'espérais pouvoir utiliser la précision horizontale pour rejeter les données récupérées lors d'un appel de didUpdateLocations avec le mode avion enclenché.. mais non, la précision n'a rien d'affolant.
Alors non je n'ai pas essayé car l'appli étant destinée aux pratiquants de loisirs aériens, la plupart du temps ils ne seront pas en zone de couverture réseau.
Un phénomène que j'ai remarqué et que je ne comprends pas concernant didFailWithError : la méthode n'est pas appelée quand je passe en mode avion. En revanche, si, étant en mode avion, je bascule sur une autre appli puis reviens sur mon appli, là la méthode est appelée.
Comment faire pour que didFailWithError soit appelée dès lors que l'iPhone est mis en mode avion ??
Ce que je veux détecter c'est l'indisponibilité du GPS, en cas de passage en mode avion.
Je suis en train d'expérimenter une autre solution : utiliser un timer, un peu à la façon d'un watchdog. Si didUpdateLocations n'a pas été appelée une seule fois depuis plusieurs secondes, je considère que le téléphone ne reçoit pas le signal GPS et donc j'en avertis l'utilisateur. C'est quand même du bricolage, ce serait tellement plus simple si Apple nous laissait lire l'état du mode avion...
En particulier si "pausesLocationUpdatesAutomatically" est à YES, ça peut donc justement arriver, pour économiser de la batterie. Or il est à YES par défaut.
D'ailleurs si ça se trouve c'est ce qui t'arrive : il détecte que la position GPS ne risque pas trop de changer, donc il met en pause le GPS, et quand tu passes en mode avion il détecte pas tout de suite que le GPS n'est plus dispo car il faut qu'il attende que tu bouges à nouveau pour qu'il tente de redémarrer le GPS et te signaler qu'il ne peut pas y accéder...
Dans l'état actuel de mon application, un peu en bourrin, j'ai l'accuracy à BestForNavigation, et je n'avais pas touché à pausesLocationUpdatesAutomatically, qui était donc à YES. Merci pour cette remarque très pertinente !!
J'ai donc fait l'essai suivant : pausesLocationUpdatesAutomatically = NO
- Hors mode avion : effectivement didUpdateLocations est appelée encore plus souvent
- Passage en mode avion :
- didUpdateLocations est encore appelée quelques fois avec une horizontal accuracy légèrement augmentée
- Sur une dizaine d'essais, didFailWithError n'a jamais été appelée, à part en mettant l'appli en tache de fond (bouton home) et en la rappelant
Donc j'ai implémenté mon compteur. La méthode fonctionne si pausesLocationUpdatesAutomatically = NO.
Maintenant il me faut :
1- Evaluer la robustesse de la méthode (compteur + filtres) avec pausesLocationUpdatesAutomatically = YES
2- Evaluer la différence d'autonomie de batterie entre pausesLocationUpdatesAutomatically = NO et YES
à noter que j'ai aussi joué avec les activityType, mais je n'ai pas trouvé de différence notable...