删除特定的本地通知

我正在开发基于本地通知的iPhone闹钟应用程序。

在删除闹钟时,相关的本地通知应该被取消。 但是,我怎样才能确定本地通知数组中的哪个对象将被取消?

我知道[[UIApplication sharedApplication] cancelLocalNotification:notification]方法,但我怎样才能得到这个'通知'来取消它?

您可以在本地通知的用户信息中保存唯一的密钥值。 获取所有本地通知,循环访问数组并删除特定的通知。

代码如下,

OBJ-C:

 UIApplication *app = [UIApplication sharedApplication]; NSArray *eventArray = [app scheduledLocalNotifications]; for (int i=0; i<[eventArray count]; i++) { UILocalNotification* oneEvent = [eventArray objectAtIndex:i]; NSDictionary *userInfoCurrent = oneEvent.userInfo; NSString *uid=[NSString stringWithFormat:@"%@",[userInfoCurrent valueForKey:@"uid"]]; if ([uid isEqualToString:uidtodelete]) { //Cancelling local notification [app cancelLocalNotification:oneEvent]; break; } } 

迅速:

 var app:UIApplication = UIApplication.sharedApplication() for oneEvent in app.scheduledLocalNotifications { var notification = oneEvent as UILocalNotification let userInfoCurrent = notification.userInfo! as [String:AnyObject] let uid = userInfoCurrent["uid"]! as String if uid == uidtodelete { //Cancelling local notification app.cancelLocalNotification(notification) break; } } 

UserNotification:

如果您使用UserNotification (iOS 10+),请按照下列步骤操作:

  1. 创buildUserNotification内容时,添加一个唯一的标识符

  2. 使用removePendingNotificationRequests(withIdentifiers :)删除特定的待处理通知

  3. 使用removeDeliveredNotifications(withIdentifiers :)删除特定的已发送通知

欲了解更多信息, UNUserNotificationCenter

其他选项:

首先,创build本地通知时,可以将其存储为用户默认值以供将来使用,本地通知对象不能直接存储在用户默认值中,此对象需要首先转换为NSData对象,然后才能存储NSData进入User defaults 。 以下是代码:

 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:localNotif]; [[NSUserDefaults standardUserDefaults] setObject:data forKey:[NSString stringWithFormat:@"%d",indexPath.row]]; 

在您存储并安排了本地通知之后,将来可能会出现需要取消之前创build的任何通知的要求,因此您可以从用户默认值中检索该通知。

 NSData *data= [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"%d",UniqueKey]]; UILocalNotification *localNotif = [NSKeyedUnarchiver unarchiveObjectWithData:data]; NSLog(@"Remove localnotification are %@", localNotif); [[UIApplication sharedApplication] cancelLocalNotification:localNotif]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:[NSString stringWithFormat:@"%d",UniqueKey]]; 

希望这可以帮助

这是我做的。

创build通知时,请执行以下操作:

  // Create the notification UILocalNotification *notification = [[UILocalNotification alloc] init] ; notification.fireDate = alertDate; notification.timeZone = [NSTimeZone localTimeZone] ; notification.alertAction = NSLocalizedString(@"Start", @"Start"); notification.alertBody = **notificationTitle**; notification.repeatInterval= NSMinuteCalendarUnit; notification.soundName=UILocalNotificationDefaultSoundName; notification.applicationIconBadgeNumber = 1; [[UIApplication sharedApplication] scheduleLocalNotification:notification] ; 

当试图删除它做到这一点:

  NSArray *arrayOfLocalNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications] ; for (UILocalNotification *localNotification in arrayOfLocalNotifications) { if ([localNotification.alertBody isEqualToString:savedTitle]) { NSLog(@"the notification this is canceld is %@", localNotification.alertBody); [[UIApplication sharedApplication] cancelLocalNotification:localNotification] ; // delete the notification from the system } } 

这个解决scheme应该适用于多个通知,而不是pipe理任何数组或字典或用户默认值。 您只需使用已经保存到系统通知数据库的数据。

希望这能帮助未来的devise师和开发者

快乐的编码家伙! :d

在swift中调度和删除通知:

  static func scheduleNotification(notificationTitle:String, objectId:String) { var localNotification = UILocalNotification() localNotification.fireDate = NSDate(timeIntervalSinceNow: 24*60*60) localNotification.alertBody = notificationTitle localNotification.timeZone = NSTimeZone.defaultTimeZone() localNotification.applicationIconBadgeNumber = 1 //play a sound localNotification.soundName = UILocalNotificationDefaultSoundName; localNotification.alertAction = "View" var infoDict : Dictionary<String,String!> = ["objectId" : objectId] localNotification.userInfo = infoDict; UIApplication.sharedApplication().scheduleLocalNotification(localNotification) } static func removeNotification(objectId:String) { var app:UIApplication = UIApplication.sharedApplication() for event in app.scheduledLocalNotifications { var notification = event as! UILocalNotification var userInfo:Dictionary<String,String!> = notification.userInfo as! Dictionary<String,String!> var infoDict : Dictionary = notification.userInfo as! Dictionary<String,String!> var notifcationObjectId : String = infoDict["objectId"]! if notifcationObjectId == objectId { app.cancelLocalNotification(notification) } } } 

iMOBDEV的解决scheme可以完美地移除特定的通知(例如,在删除警报之后),但是当您需要有select地删除已经触发并且仍在通知中心的任何通知时,它特别有用。

可能的情况是:警报通知触发,但用户打开该应用程序时不用点击该通知,并再次安排该警报。 如果您想确保通知中心只有一个通知可以在给定的项目/警报上,那么这是一个好方法。 它也可以让你不必每次打开应用程序都清除所有的通知,应该更适合应用程序。

  • 创build本地通知后,使用NSKeyedArchiver将其存储为UserDefaults Data 。 您可以创build一个与您在通知的userInfo字典中保存的内容相同的密钥。 如果它与核心数据对象关联,则可以使用其唯一的objectID属性。
  • NSKeyedUnarchiver检索它。 现在,您可以使用cancelLocalNotification方法将其删除。
  • 相应地更新UserDefaults上的键。

下面是该解决scheme的Swift 3.1版本(针对iOS 10以下的目标):

商店

 // localNotification is the UILocalNotification you've just set up UIApplication.shared.scheduleLocalNotification(localNotification) let notificationData = NSKeyedArchiver.archivedData(withRootObject: localNotification) UserDefaults.standard.set(notificationData, forKey: "someKeyChosenByYou") 

检索并删除

 let userDefaults = UserDefaults.standard if let existingNotificationData = userDefaults.object(forKey: "someKeyChosenByYou") as? Data, let existingNotification = NSKeyedUnarchiver.unarchiveObject(with: existingNotificationData) as? UILocalNotification { // Cancel notification if scheduled, delete it from notification center if already delivered UIApplication.shared.cancelLocalNotification(existingNotification) // Clean up userDefaults.removeObject(forKey: "someKeyChosenByYou") } 

Swift版本,如果需要的话:

 func cancelLocalNotification(UNIQUE_ID: String){ var notifyCancel = UILocalNotification() var notifyArray = UIApplication.sharedApplication().scheduledLocalNotifications for notifyCancel in notifyArray as! [UILocalNotification]{ let info: [String: String] = notifyCancel.userInfo as! [String: String] if info[uniqueId] == uniqueId{ UIApplication.sharedApplication().cancelLocalNotification(notifyCancel) }else{ println("No Local Notification Found!") } } } 

您传递给cancelLocalNotification:的UILocalNotification对象将匹配任何现有的具有匹配属性的UILocalNotification对象。

所以:

 UILocalNotification *notification = [[UILocalNotification alloc] init]; notification.alertBody = @"foo"; [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 

会提供一个本地通知,稍后可以通过以下方式取消:

 UILocalNotification *notification = [[UILocalNotification alloc] init]; notification.alertBody = @"foo"; [[UIApplication sharedApplication] cancelLocalNotification:notification]; 

我在Swift 2.0中使用这个函数:

  static func DeleteNotificationByUUID(uidToDelete: String) -> Bool { let app:UIApplication = UIApplication.sharedApplication() // loop on all the current schedualed notifications for schedualedNotif in app.scheduledLocalNotifications! { let notification = schedualedNotif as UILocalNotification let urrentUi = notification.userInfo! as! [String:AnyObject] let currentUid = urrentUi["uid"]! as! String if currentUid == uidToDelete { app.cancelLocalNotification(notification) return true } } return false } 

受@ KingofBliss的答复启发

在安排通知时,您可以保留带有类别标识符的string

  localNotification.category = NotificationHelper.categoryIdentifier 

并在需要时search并取消

 let app = UIApplication.sharedApplication() for notification in app.scheduledLocalNotifications! { if let cat = notification.category{ if cat==NotificationHelper.categoryIdentifier { app.cancelLocalNotification(notification) break } } } 

对于重复的提醒(例如,您希望闹钟在下午四点的星期六,星期六和星期三发生,然后您必须发出三次闹钟并将repeatInterval设置为NSWeekCalendarUnit)。

制作一次提醒:

 UILocalNotification *aNotification = [[UILocalNotification alloc] init]; aNotification.timeZone = [NSTimeZone defaultTimeZone]; aNotification.alertBody = _reminderTitle.text; aNotification.alertAction = @"Show me!"; aNotification.soundName = UILocalNotificationDefaultSoundName; aNotification.applicationIconBadgeNumber += 1; NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *componentsForFireDate = [calendar components:(NSYearCalendarUnit | NSWeekCalendarUnit| NSHourCalendarUnit | NSMinuteCalendarUnit| NSSecondCalendarUnit | NSWeekdayCalendarUnit) fromDate: _reminderDate]; [componentsForFireDate setHour: [componentsForFireDate hour]] ; //for fixing 8PM hour [componentsForFireDate setMinute:[componentsForFireDate minute]]; [componentsForFireDate setSecond:0] ; NSDate *fireDateOfNotification = [calendar dateFromComponents: componentsForFireDate]; aNotification.fireDate = fireDateOfNotification; NSDictionary *infoDict = [NSDictionary dictionaryWithObject:_reminderTitle.text forKey:kRemindMeNotificationDataKey]; aNotification.userInfo = infoDict; [[UIApplication sharedApplication] scheduleLocalNotification:aNotification]; 

重复提示:

 for (int i = 0 ; i <reminderDaysArr.count; i++) { UILocalNotification *aNotification = [[UILocalNotification alloc] init]; aNotification.timeZone = [NSTimeZone defaultTimeZone]; aNotification.alertBody = _reminderTitle.text; aNotification.alertAction = @"Show me!"; aNotification.soundName = UILocalNotificationDefaultSoundName; aNotification.applicationIconBadgeNumber += 1; NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *componentsForFireDate = [calendar components:(NSYearCalendarUnit | NSWeekCalendarUnit| NSHourCalendarUnit | NSMinuteCalendarUnit| NSSecondCalendarUnit | NSWeekdayCalendarUnit) fromDate: _reminderDate]; [componentsForFireDate setWeekday: [[reminderDaysArr objectAtIndex:i]integerValue]]; [componentsForFireDate setHour: [componentsForFireDate hour]] ; // Setup Your Own Time. [componentsForFireDate setMinute:[componentsForFireDate minute]]; [componentsForFireDate setSecond:0] ; NSDate *fireDateOfNotification = [calendar dateFromComponents: componentsForFireDate]; aNotification.fireDate = fireDateOfNotification; aNotification.repeatInterval = NSWeekCalendarUnit; NSDictionary *infoDict = [NSDictionary dictionaryWithObject:_reminderTitle.text forKey:kRemindMeNotificationDataKey]; aNotification.userInfo = infoDict; [[UIApplication sharedApplication] scheduleLocalNotification:aNotification]; } } 

过滤数组以显示它。

 -(void)filterNotficationsArray:(NSMutableArray*) notificationArray{ _dataArray = [[NSMutableArray alloc]initWithArray:[[UIApplication sharedApplication] scheduledLocalNotifications]]; NSMutableArray *uniqueArray = [NSMutableArray array]; NSMutableSet *names = [NSMutableSet set]; for (int i = 0 ; i<_dataArray.count; i++) { UILocalNotification *localNotification = [_dataArray objectAtIndex:i]; NSString * infoDict = [localNotification.userInfo objectForKey:@"kRemindMeNotificationDataKey"]; if (![names containsObject:infoDict]) { [uniqueArray addObject:localNotification]; [names addObject:infoDict]; } } _dataArray = uniqueArray; } 

要删除提醒,即使它只是一次或重复:

 - (void) removereminder:(UILocalNotification*)notification { _dataArray = [[NSMutableArray alloc]initWithArray:[[UIApplication sharedApplication]scheduledLocalNotifications]]; NSString * idToDelete = [notification.userInfo objectForKey:@"kRemindMeNotificationDataKey"]; for (int i = 0 ; i<_dataArray.count; i++) { UILocalNotification *currentLocalNotification = [_dataArray objectAtIndex:i]; NSString * notificationId = [currentLocalNotification.userInfo objectForKey:@"kRemindMeNotificationDataKey"]; if ([notificationId isEqualToString:idToDelete]) [[UIApplication sharedApplication]cancelLocalNotification:currentLocalNotification]; } _dataArray = [[NSMutableArray alloc]initWithArray:[[UIApplication sharedApplication]scheduledLocalNotifications]]; [self filterNotficationsArray:_dataArray]; [_remindersTV reloadData]; } 

我稍微扩展了KingfBliss的回答,写了一些更像Swift2的代码,删除了一些不必要的代码,并join了一些碰撞警卫。

首先,在创build通知时,您需要确保设置通知的userInfo的uid(或任何自定义属性):

 notification.userInfo = ["uid": uniqueid] 

然后,删除它时,可以这样做:

 guard let app: UIApplication = UIApplication.sharedApplication(), let notifications = app.scheduledLocalNotifications else { return } for notification in notifications { if let userInfo = notification.userInfo, let uid: String = userInfo["uid"] as? String where uid == uidtodelete { app.cancelLocalNotification(notification) print("Deleted local notification for '\(uidtodelete)'") } } 

迅捷3式:

最终私人func cancelLocalNotificationsIfIOS9(){

 //UIApplication.shared.cancelAllLocalNotifications() let app = UIApplication.shared guard let notifs = app.scheduledLocalNotifications else{ return } for oneEvent in notifs { let notification = oneEvent as UILocalNotification if let userInfoCurrent = notification.userInfo as? [String:AnyObject], let uid = userInfoCurrent["uid"] as? String{ if uid == uidtodelete { //Cancelling local notification app.cancelLocalNotification(notification) break; } } } 

}

对于iOS 10使用:

  let center = UNUserNotificationCenter.current() center.removePendingNotificationRequests(withIdentifiers: [uidtodelete])