繁体   English   中英

当用户退出区域时,删除触发的基于位置的通知

[英]Remove fired Location-Based notification when user exits region

我为我的应用设置了(默认iOS8)基于位置的通知。

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

当用户进入指定区域时,通知将正确显示在NotificationCenter

但是,我想在用户退出该区域时删除该通知消息,因为用户回家并查看通知中心直到他们收到如下所示的消息是没有意义的:

“你在XXXXX!”

有没有人尝试类似的东西? 文档不清楚如何做到这一点。

CLRegion对象具有以下特殊属性: notifyOnEntrynotifyOnExit
您需要的一切都是以这种方式更新代码:

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];

以下是解释它的Apple 文档

@property(nonatomic, copy) CLRegion *region
为此属性分配值会导致在用户跨越区域边界时传递本地通知。
区域对象本身定义在用户进入或退出区域时是否触发通知。

我昨天真的很累,无法及时完成答案。

基于这里的一些答案,我只知道你必须做什么。 我自己没有尝试过(地理围栏是一个非常痛苦的测试,我知道,因为我正在研究地理围栏项目。),我也从来没有必须删除通知中心发送的通知。

我认为您的申请不会因整个过程而终止。 所以我们不会在这里使用startMonitoringForRegion函数。

用Swift 2.0编写的答案(将它翻译成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 */
    }
}

这是我必须建立的某种伪机制,所以如果有什么不对或不正确我会很高兴听到你的反馈。 :)

这将清除通知中心的所有应用程序通知。

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

如果您按住UILocalNotification对象,似乎可以清除特定通知。 使用您在上面的示例中创建的通知对象,您可以调用

[[UIApplication sharedApplication] cancelLocalNotification:notification];

清除通知。

它看起来非常简单。 按照以下步骤,它将帮助您。

  • 制作一个可在后台继续使用的后台服务来检查您的位置。
  • 当您进入某个地区时,请点击您已完成的本地通知。 干得好。
  • 但是当您离开该区域时(检查后台服务并输入位置详细信息,例如现在位置与用户在该区域中输入时的位置详细信息匹配)。 使用空数据触发新的本地通知。 而且它也将清除通知窗口中的通知。

您应该触发一个后台方法,该方法只应在设备离开该位置时调用。 这可以通过为区域创建图层并在其离开边界时立即触发来实现。

在该方法中,您可以清除相应应用程序的所有通知

[[UIApplication sharedApplication] cancelLocalNotification:notification];

或者可以通过致电清除特定通知

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

您将收到特定应用程序的所有有效通知。 删除特定区域的特定通知。

CLLocationManagerDelegate委托具有一组基于设备位置触发的方法。 如;

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

在您的情况下,您需要做的是触发以下回调时;

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

从NotificationCenter中删除您的通知

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM