web-dev-qa-db-fra.com

Notification iBeacon lorsque l'application n'est pas en cours d'exécution

J'ai réussi à créer un iBeacon qui déclenche une notification Push locale sur mon iPhone lorsque le balise est à sa portée. Cela fonctionne parfaitement lorsque l'application est en mode arrière-plan.

Ma question est la suivante: puis-je déclencher la notification même lorsque l'application n'est pas en cours d'exécution, même en arrière-plan?

Je pensais que c'était possible mais je ne suis pas sûr. Si oui, comment puis-je accomplir cela?

Merci!

57
Lapidus

Oui, c'est possible et cela devrait être automatique.

Une fois que vous avez créé une CLBeaconRegion et commencé à en surveiller le suivi, les services de localisation gardent une trace du fait que votre téléphone se trouve ou non dans la région, même lorsque votre application n'est pas en cours d'exécution. Si votre application n'est pas en cours d'exécution pendant une transition, iOS lancera votre application en arrière-plan pendant quelques secondes pour appeler les méthodes CLLocationManagerDelegate appropriées.

J'ai découvert le comportement ci-dessus en expérimentant avec ma propre application, mais je l'ai également constaté avec le programme exemple AirLocate d'Apple. Avec AirLocate, si vous configurez une région de surveillance puis redémarrez votre téléphone, AirLocate envoie toujours une notification locale dès que le téléphone entre dans la région.

Faites attention lorsque vous testez ceci, car il faut parfois jusqu'à 4 minutes après l'activation/la désactivation d'un iBeacon pour qu'iOS reconnaisse la transition d'état de la région. [~ # ~] modifier [~ # ~] : à partir de l'iPhone 5, les applications utilisent généralement l'accélération matérielle pour détecter les balises en quelques secondes, et si l'accélération matérielle n'est pas disponible, cela peut prendre jusqu'à 15 minutes.

EDIT: À partir d'iOS 8, vous devez vous assurer d'avoir appelé et obtenu avec succès locationManager.requestAlwaysAuthorization() en tant que locationManager.requestWhenInUseAuthorization() uniquement permet de détecter les balises au premier plan.

J'ai posté une discussion détaillée sur la façon dont tout cela fonctionne dans cet article de blog.

64
davidgyoung

OK, j’ai réussi à faire fonctionner cela correctement et j’ai expérimenté avec, voici donc la réponse Voici ce que vous devez faire pour que votre application soit invoquée lors du franchissement d'une frontière de région de balise une fois l'application terminée (en supposant que votre application fonctionne correctement au premier plan):

  1. Vous devez implémenter un délégué CLLocation dans votre AppDelegate.m module. Ce délégué est ce qui est appelé par iOS, donc si vous n'avez pas le code de délégué CLLocation dans AppDelegate.m, vous ne pourrez pas répondre à iOS lorsque votre application sera fermée. C'est ce que l'application exemple AirLocate d'Apple fait.

Donc, à l'intérieur AppDelegate.m vous avez besoin des éléments suivants (vous devez également créer un lien dans CoreLocation.h):

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.

// This location manager will be used to notify the user of region state transitions when the app has been previously terminated.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
return YES;
}
  1. À l'intérieur AppDelegate.m, vous devez implémenter la méthode locationManager didDetermineState, comme suit:

    -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
    
      UILocalNotification *notification = [[UILocalNotification alloc] init];
    
      if(state == CLRegionStateInside)
      {
        notification.alertBody = [NSString stringWithFormat:@"You are inside region %@", region.identifier];
      }
      else if(state == CLRegionStateOutside)
      {
        notification.alertBody = [NSString stringWithFormat:@"You are outside region %@", region.identifier];
      }
     else
     {
       return;
     }
    
      [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
     }
    

-> Ainsi, si votre application est terminée (elle doit être exécutée au moins UNE FOIS), lorsque le périphérique passe au-delà d'une limite de balise que vous surveillez, iOS appelle votre application et appelle le locationManager:didDetermineState méthode dans votre module AppDelegate.m. Dans cette méthode, vous pouvez ensuite configurer et appeler presentLocalNotificationNow. Si votre application n'est PAS au premier plan lorsque cela se produit, iOS présentera la notification à l'écran même si elle est verrouillée. L'utilisateur devra alors appeler l'application pour plus d'informations.

Je suis à peu près sûr que la pression de la mémoire n'a rien à voir avec ça. De plus, le paramètre notifyEntryStateOnDisplay n'a rien à voir avec ce problème. Le paramètre notifyEntryStateOnDisplay n'est utilisé que lorsque l'utilisateur allume l'écran de l'appareil iOS (c.-à-d. Appuie sur la touche "accueil" ou en haut à gauche). Si l'utilisateur le fait et que notifyEntryStateOnDisplay correspond à TRUE et que le périphérique se trouve DANS la région de balise que vous surveillez, ALORS vous obtenez une notification à ce moment-là. Si cette propriété est définie sur FALSE, ce n'est pas le cas.

Bien entendu, vous devez exécuter iOS 7.1 pour que ce logiciel fonctionne correctement.

Pour plus de détails, visitez le site d'Apple documentation

18
TNBtech

Vous devez changer notifyEntryStateOnDisplay = YES pour CLBeaconRegion pour que le système réveille votre application pour l'événement d'entrée/sortie iBeacon.

Mais il y a une partie délicate. Si votre application n'est pas en cours d'exécution, le système le réactivera uniquement pour la gestion des entrées/sorties de balises si votre application a été arrêtée précédemment en raison de la pression de la mémoire système. Si l'utilisateur tue l'application en la glissant dans le dossier vue des tâches, le système ne réveillera pas votre application. Pour vérifier ce comportement, lancez votre application, mettez-la en arrière-plan, puis lancez successivement plusieurs applications consommant de la mémoire. J'ai lancé plusieurs jeux 3D avant que mon application ne soit fermée par le système en raison de la pression de la mémoire.

9
Jian Yin Shen

Il suffit de mettre à niveau votre version iOS vers la version 7.1 et de définir "notifyEntryStateOnDisplay = YES" pour que cela fonctionne comme un charme, même lorsque votre application n'est pas en cours d'exécution. J'avais ce problème plus tôt mais il a été corrigé une fois que j'ai fait cette mise à jour! Prendre plaisir..

6
Hugh Mbaezue

La seule façon dont j'ai pu faire ce travail est de surveiller les changements importants d'emplacement qui semblent faire l'affaire. Soyez averti que je n'ai pas testé cela pour tous les scénarios de périphérique ou d'utilisation.

2
Ronny Khan

Oui, nous pouvons présenter la notification locale à l’état kill ou à l’arrière-plan, il suffit de suivre les étapes,

1) Démarrez le gestionnaire d’emplacement en utilisant la classe CLLocationManager.

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

2) Créer CLBeaconRegion comme,

CLBeaconRegion *beacon_Region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:mjorVa minor:minorVa identifier:identifier];
beacon_Region.notifyEntryStateOnDisplay = YES;
beacon_Region.notifyOnEntry=YES;
beacon_Region.notifyOnExit=YES;

3) Implémentez deux méthodes de délégué de gestionnaire d'emplacement telles que,

-didEnterRegion
-didExitRegion

La méthode ci-dessus de gestion des deux emplacements fonctionnera même si votre application est détruite ou en arrière-plan. Le système gardera une trace de votre balise et lorsqu'il sortira de la plage, il déclenchera la méthode didExitRegion et, lorsqu'il arrivera dans le système, déclenchera la méthode didEnterRegion.

1
Gautam Sareriya