首页 文章

删除特定的本地通知

提问于
浏览
87

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

删除警报时,相关的本地通知应取消 . 但是,如何确定要取消本地通知数组中的哪个对象呢?

我知道 [[UIApplication sharedApplication] cancelLocalNotification:notification] 方法,但我怎么能让这个'notification'取消呢?

13 回答

  • 0

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

    localNotification.category = NotificationHelper.categoryIdentifier
    

    并搜索它并在需要时取消

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

    您可以在本地通知的userinfo中为密钥保存唯一值 . 获取所有本地通知,遍历数组并删除特定通知 .

    代码如下,

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

    SWIFT:

    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),请按以下步骤操作:

    欲了解更多信息,UNUserNotificationCenter

  • 23

    其他选择:

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

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

    存储和计划本地通知后,将来可能需要取消您之前创建的任何通知,因此您可以从用户默认值中检索它 .

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

    希望这可以帮助

  • 1

    这就是我做的 .

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

    // 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
    
        }
    
    }
    

    此解决方案应适用于多个通知,并且您不管理任何阵列或字典或用户默认值 . 您只需使用已保存到系统通知数据库的数据即可 .

    希望这有助于未来的设计师和开发者

    快乐的编码家伙! :d

  • 0

    在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)
            }
        }
    
    
    
    }
    
  • 8

    iMOBDEV的solution可以完美地删除特定通知(例如删除警报后),但是当您需要有选择地删除任何已经触发但仍在通知中心的通知时,它特别有用 .

    可能的情况是:警报的通知触发,但用户打开应用程序而不点击该通知并再次安排该警报 . 如果您想确保给定项目/警报的通知中心只能有一个通知,这是一个很好的方法 . 它还允许您不必在每次打开应用程序时清除所有通知,这样可以更好地适应应用程序 .

    • 创建本地通知后,使用 NSKeyedArchiver 将其作为 Data 存储在 UserDefaults 中 . 您可以创建一个等于're saving in the notification' userInfo字典的密钥 . 如果它与Core Data对象关联,则可以使用其唯一的objectID属性 .

    • 使用 NSKeyedUnarchiver 检索它 . 现在您可以使用cancelLocalNotification方法删除它 .

    • 相应地更新 UserDefaults 上的键 .

    这是该解决方案的Swift 3.1版本(适用于iOS 10以下的目标):

    Store

    // 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")
    

    Retrieve and delete

    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")
    }
    
  • 1

    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!")
                }
            }
        }
    
  • 6

    Swift 4 solution:

    UNUserNotificationCenter.current().getPendingNotificationRequests { (requests) in
      for request in requests {
        if request.content.categoryIdentifier == "identifier" {
          UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: ["identifier"])
        }
      }
    }
    
  • 212

    传递给 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];
    
  • 4

    我在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的答案

  • 2

    对于重复提醒(例如,您希望在下午4点在太阳,周六和周三发出警报,然后您必须发出3个警报并将repeatInterval设置为NSWeekCalendarUnit) .

    制作Once Only Reminder:

    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];
    
    }
    
  • 1

    我稍微扩展了KingofBliss的答案,写了一些类似Swift2的东西,删除了一些不必要的代码,并添加了一些防撞板 .

    首先,在创建通知时,您需要确保设置通知的 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)'")
        }
    }
    
  • 8

    迅捷3式:

    final private 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])
    

相关问题