Supprimer la notification basée sur l'location lorsque l'user quitte la région

J'ai configuré les notifications basées sur l'location (par défaut iOS8) pour mon application.

UILocalNotification *notification = [[UILocalNotification alloc] init]; notification.regionTriggersOnce = NO; notification.userInfo = @{ @"notification_id" : @"someID" }; notification.region = region; notification.alertBody = alertBody; [[UIApplication sharedApplication] scheduleLocalNotification:notification]; 

Lorsqu'un user entre dans la région spécifiée, la notification est affichée dans le NotificationCenter correctement.

Cependant, je veux supprimer ce message de notification lorsque l'user quitte cette région, car il est peu logique pour l'user de rentrer à la maison et de regarder le centre de notification jusqu'à ce qu'il reçoive un message qui ressemble à ceci:

"Vous êtes à XXXXX!"

Quelqu'un at-il essayé quelque chose de similaire? La documentation n'est pas claire sur la façon dont cela peut être fait.

CLRegion object CLRegion a des propriétés spéciales pour cela: notifyOnEntry et notifyOnExit .
Tout ce dont vous avez besoin est le code de mise à jour de cette façon:

 CLRegion *region = .... // Configure region here region.notifyOnEntry = YES; region.notifyOnExit = NO; UILocalNotification *notification = [[UILocalNotification alloc] init]; notification.regionTriggersOnce = NO; notification.userInfo = @{ @"notification_id" : @"someID" }; notification.region = region; notification.alertBody = alertBody; [[UIApplication sharedApplication] scheduleLocalNotification:notification]; 

Voici la documentation d' Apple qui l'explique:

@property(nonatomic, copy) CLRegion *region
L'affectation d'une valeur à cette propriété entraîne la remise de la notification locale lorsque l'user franchit la limite de la région.
L'object région définit lui-même si la notification est déclenchée lorsque l'user entre ou sort de la région.

J'étais vraiment fatigué hier et je n'ai pas pu compléter ma réponse à time.

Basé sur quelques réponses ici, je n'ai qu'une idée de ce que vous devez faire. Je ne l'ai pas essayé moi-même (le geofencing est vraiment difficile à tester, je le sais parce que je travaille sur un projet de geofencing atm.), Je n'ai jamais eu besoin de supprimer une notification du Centre de Notification auparavant.

Je suppose que votre request ne sera pas terminée en raison de l'set du process. Nous n'utiliserons donc pas la fonction startMonitoringForRegion ici.

Réponse écrite en Swift 2.0 (Ce n'est pas si difficile à traduire en ObjC).

 func createAndRegisterSomeNotificationSomewhere() { let region = CLCircularRegion(center: someCoordinates, radius: someRadius, identifier: someIdentifier) region.notifyOnEntry = true region.notifyOnExit = true let locationNotification = UILocalNotification() locationNotification.alertBody = "someAlertBody" locationNotification.userInfo = ["notification_id" : "someID"] locationNotification.regionTriggersOnce = false locationNotification.region = region // remember 'presentLocalNotificationNow' will not work if this value is set UIApplication.sharedApplication().scheduleLocalNotification(locationNotification) } /* CLLocationManagerDelegate provides two function */ // func locationManager(manager: CLLocationManager, didEnterRegion region: CLRegion) // func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) /* If I'm not mistaken they are only called for monitored regions and not location based local notifications */ /* I mean you will have to use something like: self.locationManager.startMonitoringForRegion(someCircularRegion) */ /* Correct me if I'm wrong. So consider to rebuild the following logic to ease everything if you want to monitor regions. */ /* Now when you receive your location notification */ func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) { if let region = notification.region { self.locationManager.requestStateForRegion(region) /* based on other answers this will remove your noticaiton from NC and cancel from showing it anywhere */ application.cancelLocalNotification(notification) /* but we need this notification still be scheduled because 'region.notifyOnExit = true' should fire it again later */ application.scheduleLocalNotification(notification) } } func locationManager(manager: CLLocationManager, didDetermineState state: CLRegionState, forRegion region: CLRegion) { /* this is not the best solution, because it adds some latency to the dilivery code and CLRegionState can also be Unknown sometimes */ /* I'd go with the two functions above if I only had up to 20 regions to monitor (max region limit per App, read CLLocationManager docs) */ /* the mechanics would be more clear and save */ switch state { case .Inside: /* create a new noticiation with the same cpecs as the cancled notification but this time withot the region */ let sameNotificationAsAbove = UILocalNotification() /* if you really need to know your IDs inside userInfo so create some good mechanics to pass these before canceling */ /* at least I would save the identifier of the region iside the noticiation */ /* save the notification somewhere to delete it later from NC */ self.someArrayToSaveDeliveredNotifications.append(sameNotificationAsAbove) /* fire the notification */ UIApplication.sharedApplication().presentLocalNotificationNow(sameNotificationAsAbove) case default: /* if it is true that notication inside NC can be deleted just by calling 'cancelLocalNotification' function */ /* so find your notification inside someArrayToSaveDeliveredNotifications bases on the region.identier which you saved inside userInfo */ let notificationToCancel = self.getNotificationForIdentifier(region.identifier) UIApplication.sharedApplication().cancelLocalNotification(notificationToCancel) /* this should delete your notification from NC based on other answers */ } } 

C'est une sorte de pseudo mécanique que je construirais si je devais, donc si quelque chose ne va pas ou pas, j'apprécierais d'entendre vos commentaires. 🙂

Cela effacera toutes les notifications de l'application à partir du Centre de notifications.

 [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0]; [[UIApplication sharedApplication] cancelAllLocalNotifications]; 

Il semble que vous puissiez effacer une notification spécifique si vous gardez l'object UILocalNotification. En utilisant votre object de notification que vous avez créé dans votre exemple ci-dessus, vous pouvez appeler

 [[UIApplication sharedApplication] cancelLocalNotification:notification]; 

pour effacer la notification.

Cela ressemble à une solution très simple. suivez les étapes ci-dessous, il vous aidera.

  • Créez un service d'arrière-plan qui fonctionnera en arrière-plan pour vérifier votre position.
  • Lorsque vous entrez dans une région, envoyez une notification locale que vous avez déjà effectuée. bon travail.
  • Mais lorsque vous quittez cette région (vérifiez le service d'arrière-plan avec les détails de l'location, comme maintenant l'location correspond aux détails de l'location lorsque l'user est entré dans cette région). triggersr la nouvelle notification locale avec des données vides. et que cela effacera la notification de la window de notification également.

Vous devez triggersr une méthode d'arrière-plan qui ne doit être appelée que lorsque le périphérique sort de l'location. Cela peut être réalisé en créant une couche pour la région et triggersr immédiatement quand elle sort de la frontière.

Dans la méthode, vous pouvez soit effacer toute la notification de l'application respective par

 [[UIApplication sharedApplication] cancelLocalNotification:notification]; 

ou peut effacer uniquement une notification spécifique en appelant

 UIApplication* application = [UIApplication sharedApplication]; NSArray* scheduledNotifications = [NSArray arrayWithArray:application.scheduledLocalNotifications]; application.scheduledLocalNotifications = scheduledNotifications; 

Vous recevrez toute la notification valide disponible pour l'application particulière. Supprimer la notification spécifique pour la région spécifique.

Le délégué CLLocationManagerDelegate dispose d'un set de methods qui sont déclenchées à partir de l'location du périphérique. Tel que;

 -(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region -(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region 

Dans votre cas, ce que vous avez à faire est lorsque le callback suivant est déclenché;

 -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region 

retirer votre notification du NotificationCenter