web-dev-qa-db-fra.com

Surveillance iOS Geofence CLCircularRegion. locationManager: didExitRegion ne semble pas fonctionner comme prévu

J'essaie actuellement d'obtenir que mon application surveille des régions particulières à l'aide de CoreLocation mais je trouve qu'elle ne semble pas fonctionner comme prévu, il me semble qu'elle ne peut pas fonctionner avec un petit rayon défini pour chaque emplacement soit 10m.

J'ai également mis en place une petite application de test qui trace le rayon du cercle sur une carte afin que je puisse voir visuellement ce qui se passe.

Le code que j'utilise pour surveiller les emplacements est le suivant:

self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;

// Set-up a region
CLLocationDegrees latitude = 52.64915;
CLLocationDegrees longitude = -1.1506367;
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);

CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:centerCoordinate
                                                                 radius:10 // Metres
                                                             identifier:@"testLocation"];

[self.locationManager startMonitoringForRegion:region];

Je n'ai pas mis le code ici pour la région DidEnter etc. car je sais que cela fonctionne quand je vais à plus de 100 m de la région surveillée.

Voici une capture d'écran de l'application lorsque je suis bien à plus de 10 mètres de l'emplacement violet sur la carte, les événements de la région de sortie ne se déclenchent pas, cependant si je change mon emplacement à Londres il se déclenche et aussi quand je remets mon emplacement à l'endroit où se trouve l'emplacement bleu actuellement, il tire également.

Example Region

Est-ce que quelqu'un sait s'il y a une limitation avec le rayon de région minimum ou peut-être que je fais quelque chose de mal.

Merci Aaron

28
MonkeyBlue

Je ne pense pas que la surveillance des régions fonctionnera bien pour un si petit rayon.

  • La meilleure précision avec la puce GPS et kCLLocationAccuracyBestForNavigation est souvent de seulement 10 mètres.
  • Apple dit (dans le Emplacement et cartes PG ) que la distance minimale pour les régions devrait être supposée être de 200 m
  • J'ai entendu dire que la surveillance de la région utilise le WiFi pour obtenir sa position (ce qui est logique pour les économies d'énergie). La précision du WiFi est plus proche de 20m-100m. Je ne sais pas comment une autre application utilisant l'emplacement en arrière-plan (c'est-à-dire en utilisant le GPS) affecterait cela. Probablement, le gestionnaire de sites partagerait des informations pour améliorer la précision.
  • La surveillance de région peut prendre 30 secondes pour se déclencher une fois à l'intérieur d'une région et quelques minutes pour se déclencher après avoir quitté une région (pour éviter que des problèmes de localisation ne la déclenchent).
  • Lorsque la surveillance des régions a été introduite pour la première fois, ils ont déclaré que cela ne fonctionnerait qu'avec 100 millions de régions et que tout ce qui était plus petit serait augmenté. Cela se produit probablement encore.
  • Il existe une méthode obsolète startMonitoringForRegion:desiredAccuracy: qui vous a permis de spécifier la distance au-delà de la frontière de la région pour commencer à générer des notifications. Vraisemblablement, cette fonctionnalité a été intégrée à startMonitoringForRegion: mais est toujours là. Une région de 10 m peut se retrouver avec un tampon de 10 m.
  • Si vous souhaitez le faire, spécifiez une région plus grande autour de laquelle vous souhaitez surveiller, et lorsque l'appareil se réveille dans cette région, démarrez les mises à jour de la localisation en arrière-plan (GPS) et utilisez CLCircularRegion's -containsCoordinate: pour se déclencher lorsque l'appareil se trouve à moins de 10 m manuellement. Cette méthode est officiellement sanctionnée par Apple (voir WWDC 201 session 307).

À partir des documents CLCircularRegion:

N'oubliez pas que le gestionnaire d'emplacement ne génère pas de notifications dès le franchissement d'une limite de région. Au lieu de cela, il applique des critères de temps et de distance pour garantir que la traversée était prévue et devrait véritablement déclencher une notification. Choisissez donc un point central et un rayon appropriés et laissez-vous suffisamment de temps pour alerter l'utilisateur.

Depuis le Emplacement & Maps PG :

Les événements de région peuvent ne pas se produire immédiatement après le franchissement d'une frontière de région. Pour éviter les notifications parasites, iOS ne fournit pas de notifications de région tant que certaines conditions de seuil ne sont pas remplies. Plus précisément, l'emplacement de l'utilisateur doit traverser la limite de la région, s'éloigner de la limite d'une distance minimale et rester à cette distance minimale pendant au moins 20 secondes avant que les notifications soient signalées.
Les distances de seuil spécifiques sont déterminées par le matériel et les technologies de localisation actuellement disponibles. Par exemple, si le Wi-Fi est désactivé, la surveillance des régions est nettement moins précise. Cependant, à des fins de test, vous pouvez supposer que la distance minimale est d'environ 200 mètres.

Il y a plus d'informations à l'intérieur de cet article de Kevin McMahon , qui a interrogé les ingénieurs de Core Location sur la surveillance des régions dans un laboratoire à la WWDC 2012. Cette information aura changé entre-temps, mais la partie sur les catégories de régions est intéressant. Voici un montage:

Région fine (0 - 150m)
- Avec un plancher de 100 m, la portée de cette catégorie est effectivement de 100 à 150 m.
- Pour les régions, les performances de cette taille dépendent fortement du matériel lié à l'emplacement
- Le temps nécessaire à l'emplacement central pour détecter et appeler la méthode déléguée appropriée est d'environ 2 à 3 minutes en moyenne après le franchissement de la limite de la région.
.

51
nevan king

Cela semble être un bogue dans CLLocationManager. J'ai effectué des tests approfondis en utilisant diverses configurations de rayon de région et locationManager:didExitRegion ne se déclenche pas comme prévu. Cela semble être soit un bug plutôt méchant, soit la surveillance de la région ne se produit pas du tout comme le suggère la documentation. J'ai le harnais de test à la disposition de tous ceux qui le souhaitent:

http://www.mediafire.com/download/x863zkttltyalk6/LocationTest.Zip

Exécutez-le dans le simulateur et lancez le test en sélectionnant Debug -> Location -> Freeway Drive dans le menu du simulateur iOS. Le nombre que vous voyez est la distance du centre de la région surveillée. La couleur d'arrière-plan sera verte lorsque l'appareil se trouve dans la région surveillée et rouge lorsqu'elle se trouve à l'extérieur de la région. Le texte sous la distance sont des journaux d'événements.

enter image description here

Après avoir exécuté l'application, vous devriez voir locationManager:didExitRegion incendie à 5319 mètres de la région surveillée. L'itinéraire fera une boucle toutes les 37 minutes et vous verrez l'appareil quitter la région toujours à 5319 mètres.

J'ai envoyé un radar avec Apple (17064346) . Je mettrai à jour cette réponse une fois que j'entendrai parler d'eux. Au moins alors nous aurons une entrée de la source canonique.

Voici le texte détaillé envoyé à Apple:

En utilisant une application de test sur le simulateur iOS ainsi que sur un iPhone 5S, le CLLocationManager ne semble pas déclencher les rappels didExitRegion de la manière attendue. Quel que soit le rayon de la zone circulaire surveillée, le rappel n'aura lieu qu'après avoir atteint un seuil d'environ 5000 mètres.

Étapes à reproduire:
1. Exécutez l'application jointe
2. Démarrez le suivi des régions en sélectionnant Déboguer -> Emplacement -> Freeway Drive dans le simulateur iOS
3. Surveillez l'application. Le grand # indique la distance du centre de la région surveillée.
4. Après environ 190 secondes et 5300 mètres, la sortie de la région se déclenchera enfin.

Ce problème ne semble pas du tout lié à la taille de la région. Selon les Apple docs , même les petites régions sont prises en charge:

Dans iOS 6, les régions d'un rayon compris entre 1 et 400 mètres fonctionnent mieux sur les appareils iPhone 4S ou ultérieurs. (Dans iOS 5, les régions d'un rayon compris entre 1 et 150 mètres fonctionnent mieux sur les appareils iPhone 4S et ultérieurs.) Sur ces appareils, une application peut s'attendre à recevoir la région appropriée entrée ou la région quittée en moins de 3 à 5 minutes en moyenne, sinon plus tôt.

Bien que les événements régionaux ne se produisent pas instantanément, ils devraient se produire assez rapidement. Depuis Apple docs :

Les événements de région peuvent ne pas se produire immédiatement après le franchissement d'une frontière de région. Pour éviter les notifications parasites, iOS ne fournit pas de notifications de région tant que certaines conditions de seuil ne sont pas remplies. Plus précisément, l'emplacement de l'utilisateur doit traverser la limite de la région, s'éloigner de la limite d'une distance minimale et rester à cette distance minimale pendant au moins 20 secondes avant que les notifications soient signalées.

Ce n'est pas du tout ce que je vois dans le harnais de test. Sur le simulateur, l'appareil sera toujours à plus de 5000 mètres de la région avant un locationManager:didExitRegion l'événement se produit.

24
memmons

J'aime les réponses de Michael et Nevan. Je voudrais ajouter plus d'informations sur mon expérience/opinion personnelle dans le développement d'une application iOS basée sur la localisation avec la surveillance de la région et souligner également certains points importants: -

Soyez réaliste sur la surveillance des régions

La surveillance de région utilise le système de positionnement global (GPS), le Wifi et d'autres technologies pour déterminer si l'appareil se trouve à l'intérieur ou à l'extérieur de la région surveillée. N'oubliez pas que notre terre fait 510 kilomètres carrés et environ 30% sont des terres (149 millions de km2). C'est un immense domaine. Rappelez-vous le récent étui manquant du MH370? Notre technologie actuelle la plus avancée n'a même pas pu localiser une région estimée de cet avion manquant.

Si vous souhaitez surveiller une petite région avec seulement 10 mètres de rayon . Il pourrait éventuellement fonctionner dans une ville très dense avec beaucoup de tours de téléphonie cellulaire et des zones connectées au wifi. Mais en même temps, le signal pourrait être bloqué par des tours de grande hauteur, ce qui pourrait entraîner une perte de signal pendant quelques secondes/minutes, ce qui aurait retardé la remise de la notification.

Donc, vous devez vraiment considérer les informations ci-dessus avant de décider de la taille de la région que vous souhaitez surveiller. Personnellement, je pense que le rayon de 10 mètres est trop petit.

Soyez réaliste sur le nombre de régions surveillées

La technologie Core Location actuelle ne peut surveiller que jusqu'à maximum 20 régions sur une seule application. Assurez-vous également que les régions surveillées ne sont pas trop proches les unes des autres.

Personnellement, j'ai testé 3 régions d'environ 100 mètres de rayon et à environ 200 mètres l'une de l'autre. Parfois, je peux recevoir des notifications de ces trois régions lorsque je les traverse, mais parfois, je ne peux obtenir la notification que de la première région. Quelle pourrait être la raison? Je ne pouvais pas savoir. Les régions sont peut-être trop proches les unes des autres. Ou les tours cellulaires décident que mon appareil ne se trouve pas réellement à l'intérieur de la région surveillée.

Il y avait une personne sur StackOverFlow qui veut surveiller 1800 points sur notre Terre. Ne soyez pas comme lui car il est assez irréaliste et ne comprend probablement pas la limitation du courant Core Location La technologie. Lien : Vérifiez si l'emplacement de l'utilisateur est proche de certains points

Affiner le LocationManager

Si votre application doit surveiller une petite zone ou a besoin d'une mise à jour fréquente de l'emplacement. Voici les propriétés potentielles de votre gestionnaire d'emplacement.

self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;

kCLLocationAccuracyBestForNavigation consommera plus de batterie que kCLLocationAccuracyBest. Mais, ce sera plus précis.

J'ai trouvé un problème dans la surveillance des régions dans iOS 7 lorsqu'il y a plusieurs notifications déclenchées en même temps dans différentes régions surveillées. J'ai trouvé une solution pour filtrer ce problème. Pour plus d'informations, veuillez visiter: Region Monitoring Glitch sur iOS 7 - Plusieurs notifications en même temps

Ne soyez pas trop ambitieux

Vous avez peut-être utilisé certaines applications qui peuvent surveiller une petite région et sont très précises et capables de vous avertir dès que vous entrez dans la région. Et vous avez l'inspiration pour développer exactement la même application pour rivaliser avec eux. Mais comprenez-vous ce qui se passe derrière la scène? Quelles technologies supplémentaires utilisent-ils? Et avec quels partenaires ils collaborent?

J'ai fait des recherches à ce sujet et j'ai découvert que certaines des technologies qu'ils utilisent ne sont pas accessibles au public. Certaines de ces sociétés sont fortement financées et pourraient payer une prime aux sociétés de télécommunications afin d'obtenir la meilleure précision de localisation pour la meilleure expérience utilisateur. Je ne comprends pas les détails de son fonctionnement. Je crois que la plupart de la détermination de l'emplacement se fait en fait sur le serveur (back-end), pas sur le mobile (front-end).

Ainsi, les applications développées par ces sociétés peuvent non seulement localiser le meilleur emplacement précis, mais elles consomment également peu de batterie.

[~ # ~] note [~ # ~] : Je veux juste partager mes 2 cents. Les informations ci-dessus correspondent à mon expérience et à mon opinion personnelle. Il pourrait ne pas être précis à 100% car j'apprends encore Emplacement du noyau et Surveillance de la région .

16
Ricky

Je suis d'accord avec Michael G. Emmons, et je veux aussi partager mon expérience:

J'ai testé mon code avec trois régions comme indiqué dans l'image ci-dessous:

enter image description here

Explication du comportement:

  • Mon emplacement actuel est Region-1, et je commence à surveiller les trois régions ci-dessus, et j'appelle à requestStateForRegion, pour déterminer, s'il y a une région à l'intérieur, où je me trouve actuellement.
  • Ensuite, je reçois des notifications "Entrée" pour les deux premières régions (région-1 et région 2), mais il ne devrait détecter que la région-1.
  • Maintenant, lorsque j'entre dans la région-2, je reçois la notification d'entrée pour la région-3. mais je devrais recevoir la notification pour la région-2 ici.
  • Maintenant, lorsque j'entre à nouveau dans la région-1, je reçois l'événement Quitter pour la région-3, et cela continue.
  • mais je n'obtiens aucun événement Entrée/Sortie pour les deux premières régions, jusqu'à ce que je m'éloigne d'au moins plus de 7 km-10 km des deux premières régions.

Comportement attendu: - L'événement Entrée/Sortie ne doit être déclenché que lorsque je franchis la frontière des régions, ou à l'intérieur des régions, pas avant 500 mètres de la région.

Mon hypothèse:

  • Ce que j'ai remarqué après toute l'expérience, c'est que lorsque j'appelle "requestStateForRegion" pour les trois régions,
  • il détecte toutes les régions à l'intérieur de la région de rayon 5000m, c'est pourquoi il détecte les deux premières régions en même temps (région-1 crée un cercle de 5000m de rayon, et la région-2 est à sa portée, c'est pourquoi la région -2 est également détectée ).
  • et lorsque l'utilisateur se déplace de plus de 10 km, ses événements de sortie sont appelés et lorsque l'utilisateur revient dans ces régions, son événement d'entrée est déclenché. C'est le même cas que celui expliqué par Aaron Wardle ci-dessus.
  • La région-3 est détectée, car, lorsque l'utilisateur entre dans la région-1, c'est-à-dire. 8-9 km de la région-3, donc l'événement de sortie est déclenché pour cela, et lorsque l'utilisateur est sur la route de la région-2, ici même lorsque la région-3 est à 5000 mètres, il détecte toujours la région-3 et le feu , Entrez l'événement pour la région-3.

Je pense donc que toutes les régions à l'intérieur de 5000 mètres sont détectées et que l'utilisateur s'éloigne à 10 km de la région détectée, son événement de sortie sera déclenché. sinon, si l'utilisateur se trouve dans la plage de 5 km, il ne l'appellera plus jamais événements d'entrée/sortie.

Veuillez me mettre à jour si quelqu'un a résolu ce problème ou Apple documents n'importe où sur ce problème.

6
nidIOS

Cela ressemble plus à un commentaire important. De Surveillance de région et iBeacon

Test de la prise en charge de la surveillance des régions d'une application iOS

Lorsque vous testez votre code de surveillance de région dans iOS Simulator ou sur un appareil, sachez que les événements de région peuvent ne pas se produire immédiatement après le franchissement d'une limite de région. Pour éviter les notifications parasites, iOS ne fournit pas de notifications de région tant que certaines conditions de seuil ne sont pas remplies. Plus précisément, l'emplacement de l'utilisateur doit traverser la limite de la région, s'éloigner de la limite d'une distance minimale et rester à cette distance minimale pendant au moins 20 secondes avant que les notifications soient signalées .

Les distances de seuil spécifiques sont déterminées par le matériel et les technologies de localisation actuellement disponibles. Par exemple, si le Wi-Fi est désactivé, la surveillance des régions est nettement moins précise . Cependant, à des fins de test, vous pouvez supposer que la distance minimale est d'environ 200 mètres .

2
Honey

Sons comme même 1 mètre devrait fonctionner (et mieux sur les appareils iPhone 4S +):

startMonitoringForRegion:

(...)

Dans iOS 6, les régions avec un rayon compris entre 1 et 400 mètres fonctionnent mieux sur les appareils iPhone 4S ou ultérieurs. (Dans iOS 5, les régions d'un rayon compris entre 1 et 150 mètres fonctionnent mieux sur les appareils iPhone 4S et ultérieurs.) Sur ces appareils, une application peut s'attendre à recevoir la région appropriée entrée ou la région quittée en moins de 3 à 5 minutes en moyenne, sinon plus tôt.

1
Rivera

Sur la base de la réponse de @ Nevan, qui indiquait une sorte de couverture dans la WWDC 2013 307 (qui ne traitait pas directement de cela), j'ai trouvé une solution raisonnable pour obtenir une précision <10 m pour l'arrivée à un endroit, même si j'ai le sentiment que l'implémentation de -(void)locationManager:didVisit: pourrait rendre cela plus économe en batterie, mais fournirait des mises à jour moins fréquentes.

Tout d'abord, ayez certaines régions avec un rayon de 0..150m et commencez la surveillance. Cela n'a pas vraiment d'importance, car le système semble les déclencher à environ 150 ~ 200 m:

_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;

CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(location.lat, location.lng) radius:50 identifier:location.name];
[_locationManager startMonitoringForRegion:region];

Ensuite, implémentez

-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
    for (CLCircularRegion *enteredRegion in _locationManager.monitoredRegions.allObjects) {
        if ([enteredRegion.identifier isEqualToString:region.identifier]) {

            self.locationManager.activityType = CLActivityTypeFitness;
            self.locationManager.distanceFilter = 5;
            [self.locationManager startUpdatingLocation];

            break;
        }
    }
}

Le système commencera à surveiller et à signaler à votre délégué un flux d'emplacements, même si votre application est suspendue (besoin de UIBackgroundModes pour inclure location élément de tableau).

Pour vérifier si l'un de ces emplacements se trouve au centre d'une de vos régions, implémentez:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    CLLocation *firstLocation = [locations firstObject];
    CGFloat const DESIRED_RADIUS = 10.0;

    CLCircularRegion *circularRegion = [[CLCircularRegion alloc] initWithCenter:firstLocation.coordinate radius:DESIRED_RADIUS identifier:@"radiusCheck"];

    for (CLCircularRegion *enteredRegion in _locationManager.monitoredRegions.allObjects) {
        if ([circularRegion containsCoordinate:enteredRegion.center]) {
            [_locationManager stopUpdatingLocation];
            NSLog(@"You are within %@ of %@, @(DESIRED_RADIUS), enteredRegion.identifier);            
            break;
        } else if ([enteredRegion containsCoordinate:circularRegion.center]) {
            NSLog(@"You are within the region, but not yet %@m from %@", @(DESIRED_RADIUS), enteredRegion.identifier);
        }
    }
}

Vous voudrez également implémenter:

-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
    [_locationManager stopUpdatingLocation];
}
1
James Perih

Au cours des derniers jours, iv'e a testé une fonctionnalité de géorepérage sur mon appareil iOS 8.1 (iPhone 5S) pour une application développée par iv'e.
L'application enregistre quelques régions au service iOS gefence. La logique de l'application nécessite que chaque rayon de clôture géographique se situe entre 40 et 80 mètres.
. Autrement dit, dans les quartiers du centre-ville, les zones commerciales, etc., la détection de barrière géographique fonctionne correctement.

Malheureusement, l'inverse se produit dans les zones avec peu de tours cellulaires et de réseaux wifi. Mon quartier, par exemple, mesure environ 1000 mètres de largeur et 500 de hauteur (1 km x 0,5 km), et il y a pas de tours de cellule. Il y a peu de tours de cellule pensées, sur le périmètre qui entoure le quartier. Malheureusement Dans le périmètre du quartier, le service de geofence détecte rien.

Inutile de dire que je teste avec le Wifi activé sur l'appareil.

Lorsque je teste mon application sur Android: le service de géofencing sur Android 4.3, 4.4 & 5.1 fonctionne beaucoup mieux que sur iOS. Le service de géofencing d'Android ne détecte pas 100% des transitions de région, mais il détecte 50% à 90% des transitions régionales.

Je conclus ce qui suit: S'il y avait eu plus de tours de cellules et de points chauds Wifi et si Apple aurait amélioré le service de géorepérage, alors la détection sur les appareils iOS aurait été aussi bonne que celle d'Android .

0
Omeriko