当iOS 10中的UNUserNotificationCenterDelegate新通知到达时,如何删除先前发送的通知?

这个问题是关于iOS 10中新的UserNotifications框架。

我有一个应用程序,在用户在应用程序中执行特定操作后每半小时安排一次本地通知,从1小时开始。

为了避免混淆用户的locking屏幕或通知中心,我只需要一次显示一条通知,因此只有一条通知包含最新的相关信息。 我的计划是在每次发布新通知时清除所有已发送的通知。

看来这应该是可能的UNUserNotificationCenterDelegate新的willPresent方法,但它不像我所期望的那样。

这里有一个function,我打电话来设置所有的通知,从应用程序中的事件后1小时开始,每半小时安排一次通知,直到事件发生后23.5小时的最后一个通知:

 func updateNotifications() { for hour in 1...23 { scheduleNotification(withOffsetInHours: Double(hour)) scheduleNotification(withOffsetInHours: Double(hour) + 0.5) } } 

这是实际上根据mostRecentEventDate (这是在别处设置的Date安排通知的函数:

 func scheduleNotification(withOffsetInHours: Double) { // set up a Date for when the notification should fire let offsetInSeconds = 60 * 60 * withOffsetInHours let offsetFireDate = mostRecentEventDate.addingTimeInterval(offsetInSeconds) // set up the content of the notification let content = UNMutableNotificationContent() content.categoryIdentifier = "reminder" content.sound = UNNotificationSound.default() content.title = "Attention!" content.body = "It has been \(withOffsetInHours) hours since the most recent event." // set up the trigger let triggerDateComponents = Calendar.current.components([.year, .month, .day, .hour, .minute, .second], from: offsetFireDate) let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDateComponents, repeats: false) // set up the request let identifier = "reminder\(withOffsetInHours)" let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger) // add the request for this notification UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in if error != nil { print(error) } }) } 

在我的UNUserNotificationCenterDelegate我有这样设置的willPresent方法:

 func userNotificationCenter(_: UNUserNotificationCenter, willPresent: UNNotification, withCompletionHandler: (UNNotificationPresentationOptions) -> Void) { print("will present...") UNUserNotificationCenter.current().removeAllDeliveredNotifications() withCompletionHandler([.alert,.sound]) } 

我知道willPresent函数正在调用,因为它打印“将出现…”,但通知中心的现有通知不会被清除。 有谁知道为什么这不起作用? 或者如果有办法让它按照我想要的方式工作?


编辑:我想出了一个替代方法来实现相同的事情,但它似乎也没有工作。

我的想法是使用willPresent来静音传入的预定通知,同时安排另一个通知立即到达(没有触发器)。 所有计划到达的通知都会立即具有相同的标识符,因此现有的带有该标识符的通知应该总是被replace,就像2016年WWDC在20:00左右的例子中关于新的UserNotifications框架一样。 这里是我更新的willPresent方法:

 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent: UNNotification, withCompletionHandler: (UNNotificationPresentationOptions) -> Void) { let identifier = willPresent.request.identifier if identifier != "reminder" { let offsetInHoursString = identifier.replacingOccurrences(of: "reminder", with: "") let content = UNMutableNotificationContent() content.categoryIdentifier = "reminder" content.sound = UNNotificationSound.default() content.title = "Attention!" content.body = "It has been \(offsetInHoursString) hours since the most recent event." let identifier = "hydrationReminder" let request = UNNotificationRequest(identifier: identifier, content: content, trigger: nil) center.add(request, withCompletionHandler: { (error) in if error != nil { print(error) } }) withCompletionHandler([]) } else { withCompletionHandler([.alert,.sound]) } } 

编辑:我终于意识到, willPresent 只会被称为如果应用程序在前台,因为它说在这个页面的顶部,所以这些方法都不应该实际上工作。 我以为每次收到通知时都会调用willPresent 。 回到绘图板上的这个“只有最新,最相关的通知”的想法…

你可以查看这个演示 。

我想你要实现的function叫做“更新通知”。

iOS 10允许更新notification.All你只是做 – 保持通知具有相同的标识符

我们来看一个演示:

  1. 第一次通知:
  NSURL * imageUrl = [[NSBundle mainBundle] URLForResource:@"dog" withExtension:@"png"]; UNNotificationAttachment *imgAtt = [UNNotificationAttachment attachmentWithIdentifier:@"image" URL:imageUrl options:nil error:&error]; NSURL * mp4Url = [[NSBundle mainBundle] URLForResource:@"media" withExtension:@"mp4"]; UNNotificationAttachment *mediaAtt = [UNNotificationAttachment attachmentWithIdentifier:@"image" URL:mp4Url options:nil error:&error]; UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc]init]; //在通知中心显示的总是第一个多媒体资源content.attachments = @[imgAtt,mediaAtt]; content.badge = @1; content.title = @"Wake Up"; content.subtitle = @"First time"; content.body = @"next time。。。 "; content.categoryIdentifier = @"wakeup"; content.launchImageName = @"dog"; content.sound = [UNNotificationSound defaultSound]; // content.threadIdentifier = @""; content.userInfo = @{@"first":@"5:00 am",@"second":@"6:00"}; UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0 repeats:NO]; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"com.junglesong.pushtestdemo.wakeup" content:content trigger:trigger]; [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { NSLog(@"wake up message has been deliverd!"); }]; 多媒体资源  NSURL * imageUrl = [[NSBundle mainBundle] URLForResource:@"dog" withExtension:@"png"]; UNNotificationAttachment *imgAtt = [UNNotificationAttachment attachmentWithIdentifier:@"image" URL:imageUrl options:nil error:&error]; NSURL * mp4Url = [[NSBundle mainBundle] URLForResource:@"media" withExtension:@"mp4"]; UNNotificationAttachment *mediaAtt = [UNNotificationAttachment attachmentWithIdentifier:@"image" URL:mp4Url options:nil error:&error]; UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc]init]; //在通知中心显示的总是第一个多媒体资源content.attachments = @[imgAtt,mediaAtt]; content.badge = @1; content.title = @"Wake Up"; content.subtitle = @"First time"; content.body = @"next time。。。 "; content.categoryIdentifier = @"wakeup"; content.launchImageName = @"dog"; content.sound = [UNNotificationSound defaultSound]; // content.threadIdentifier = @""; content.userInfo = @{@"first":@"5:00 am",@"second":@"6:00"}; UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5.0 repeats:NO]; UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"com.junglesong.pushtestdemo.wakeup" content:content trigger:trigger]; [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { NSLog(@"wake up message has been deliverd!"); }]; 

你可以使用removeDeliveredNotifications(withIdentifiers 🙂