【问题标题】:Cancel UILocalNotification取消 UILocalNotification
【发布时间】:2010-07-01 13:32:44
【问题描述】:

我的 UILocalNotification 有问题。

我正在用我的方法安排通知。

- (void) sendNewNoteLocalReminder:(NSDate *)date  alrt:(NSString *)title
{
    // some code ...
    UILocalNotification *localNotif = [[UILocalNotification alloc] init]; 

    if (localNotif == nil)  
        return;

    localNotif.fireDate = itemDate; 
    localNotif.timeZone = [NSTimeZone defaultTimeZone];
    localNotif.alertAction = NSLocalizedString(@"View Details", nil); 
    localNotif.alertBody = title;
    localNotif.soundName = UILocalNotificationDefaultSoundName; 
    localNotif.applicationIconBadgeNumber = 0;

    NSDictionary *infoDict = [NSDictionary dictionaryWithObject:stringID forKey:@"id"]; 
    localNotif.userInfo = infoDict; 

    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif]; 
    [localNotif release];
}

它工作正常,我正确地收到了通知。问题是我什么时候应该取消通知。我正在使用这种方法。

- (void) deleteNewNoteLocalReminder:(NSString*) reminderID noteIDe:(NSInteger)noteIDE
{
    [[UIApplication sharedApplication] cancelLocalNotification:(UILocalNotification *)notification ????  
}

我不确定在这里做什么,但我的问题是:

我如何知道我应该删除哪个 UILocalNotification 对象?
有没有办法列出所有通知?

我唯一拥有的是我应该删除的提醒的 ID。
我正在考虑将 UILocalNotification 对象保存在我的“Note”对象中并以这种方式获取它,当我保存到我的 SQLite 数据库时序列化对象等等......有没有更聪明的方法?

【问题讨论】:

    标签: iphone cocoa-touch notifications ios4


    【解决方案1】:

    我的解决方案是使用UILocalNotification userInfo 字典。事实上,我所做的是为我的每个通知生成一个 唯一 ID(当然,这个 ID 是我以后可以检索的),然后当我想要要取消与给定 ID 关联的通知,我将使用数组简单地扫描所有可用通知:

    [[UIApplication sharedApplication] scheduledLocalNotifications]
    

    然后我尝试通过调查 ID 来匹配通知。例如:

    
    NSString *myIDToCancel = @"some_id_to_cancel";
    UILocalNotification *notificationToCancel=nil;
    for(UILocalNotification *aNotif in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
      if([[aNotif.userInfo objectForKey:@"ID"] isEqualToString:myIDToCancel]) {
         notificationToCancel=aNotif;
         break;
      }
    }
    if(notificationToCancel) [[UIApplication sharedApplication] cancelLocalNotification:notificationToCancel];
    

    我不知道这种方法在存档/取消存档方面是否更好,但是它可以工作并将数据保存为仅一个 ID。

    编辑:缺少刹车

    【讨论】:

    • 我试过你的方法,但对我不起作用。你能告诉我有什么问题吗? stackoverflow.com/questions/9139586/…
    • 你没有在你的解决方案中使用我的方法。当您使用整个对象时,我的解决方案会传递一个 ID。从您的代码看来,通知对象有一些早期的释放,这就是“无法识别的选择器”的原因(这通常发生在旧对象位置已被另一种对象重用时)。尝试在发送 cancelNotification 消息之前获取对象的类名以对其进行挖掘,这可能有助于调试。此外,当您分配“theNotification”时,请使用“self.theNotification = ...”而不是“theNotificaiton = ...”
    • 非常感谢!您实际上启发了我在每个可以添加的单元格上添加一个按钮:cancelLocalNotification atindex [sender tag],它的工作原理比带一个 uialertview 好得多。正如你所说,对象的名称现在就在取消之前,它工作得很好!
    • 是的,我在您的问题中看到了您的“自我回答”。我同意您的观点,即添加按钮然后取消其选择器上的通知对于您的特定情况完全有效。
    • 如果使用 CoreDate,我发现使用唯一的托管对象 ID:NSManagedObjectID *moID = [managedObject objectID]; 很有帮助。由于 CoreData 仅在保存后分配一个永久 ID,您可以使用:BOOL isTemporary = [[managedObject objectID] isTemporaryID];
    【解决方案2】:

    您可以从scheduledLocalNotifications 获取所有预定通知的列表,也可以全部取消:

      [[UIApplication sharedApplication] cancelAllLocalNotifications];
    

    【讨论】:

    • 我知道 cancelAllLocalNotifications 但我只想取消一个特定的。 ScheduledLocalNotifications 可能会起作用....我会尝试。
    【解决方案3】:

    我的解决方案是归档您使用 NSKeyedArchiver 安排的 UILocalNotification 对象并将其存储在某处(首选 plist 中)。然后,当您想取消通知时,请在 plist 中查找正确的数据并使用 NSKeyedUnarchiver 取消归档。 代码很简单:

    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:notice];
    

    和

    UILocalNotification *notice = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    

    【讨论】:

    • 您还可以使用 Base64 编码从 archievedDataWithRootObject 序列化 NSData,然后保存到您已有的 JSON 对象中。
    • @RafaelSanches 对线程坏死感到抱歉。但是,如果目标是存储/检索 uilocalnotification 以供以后删除,那么使用 JSON 对象有什么好处?
    【解决方案4】:

    我的解决方案是您在创建 UILocalNotification 时创建一个 NSMutableDictionary 并将该通知存储为键值作为您的 ID 并将此 NSMutableDictionay 放入您的 NSUserDefaults

    因此,当您当时想取消任何特定的本地通知时,您可以编写 [dictionary valueforkey @"KEY"] 作为密钥传递您的 id 以便您获得特定的本地通知并将其传递给

     [[UIApplication sharedApplication] scheduleLocalNotification:localNotif]; 
    

    【讨论】:

      【解决方案5】:

      斯威夫特 5:

      UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: arrayContainingIdentifiers)
      

      【讨论】:

      • 以防任何 Xamarin 开发人员寻找答案。这个对我来说很好用。 UNUserNotificationCenter.Current.RemovePendingNotificationRequests(new string[] { NotificationId });
      【解决方案6】:

      在 swift 中,您首先通过以下方式将 dict 添加到通知 userInfo:

      let dict:NSDictionary = ["ID" : "someString"]
      notification.userInfo = dict as! [String : String]
      

      然后,您想要获取一组现有通知 (2),并遍历每个通知 (3),直到找到您要查找的通知。找到后,将其取消 (4)。

      // 1. Pass in the string you want to cancel
      func cancelLocalNotification(uniqueId: String){
      
          // 2. Create an array of notifications, ensuring to use `if let` so it fails gracefully
          if let notifyArray = UIApplication.sharedApplication().scheduledLocalNotifications {
      
              // 3. For each notification in the array ...
              for notif in notifyArray as [UILocalNotification] {
                  // ... try to cast the notification to the dictionary object
                  if let info = notif.userInfo as? [String: String] {
      
                      // 4. If the dictionary object ID is equal to the string you passed in ...
                      if info["ID"] == uniqueId {
                          // ... cancel the current notification
                          UIApplication.sharedApplication().cancelLocalNotification(notif)
                      }
                  }
              }
          }
      }
      

      【讨论】:

      • 注意:UIApplication.sharedApplication() 现在是 UIApplication.shared
      【解决方案7】:

      Swift 版本:

      UIApplication.sharedApplication().cancelAllLocalNotifications()
      

      【讨论】:

        【解决方案8】:

        使用用户信息取消特定“本地通知”的 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!")
                    }
                }
            }
        

        【讨论】:

          【解决方案9】:

          我的解决方案是删除这些方法上的所有预定通知。

          -applicationDidFinishLaunchingWithOptions: 
          - (void)applicationDidBecomeActive:(UIApplication *)application;
          - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
          

          与

          [[UIApplication sharedApplication] cancelAllLocalNotifications];

          您仍然可以通过使用访问激活您的应用的 LocalNotification 对象。

              UILocalNotification *localNotif = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey];
          

          然后我在

          上重新安排新的通知
          - (void)applicationDidEnterBackground:(UIApplication *)application;
          

          这避免了对所有通知进行簿记。我也在 userInfo 字典中发送了一些上下文信息。这有助于跳转到应用中的正确位置。

          【讨论】:

            【解决方案10】:

            感谢@viggio24 的好答案,这是一个快速的版本

            var notifyCancel = UILocalNotification()
            var notifyArray=UIApplication.sharedApplication().scheduledLocalNotifications
            var i = 0
            while(i<notifyArray.count){
                if let notify = notifyArray[i] as? UILocalNotification{
                    if let info = notify.userInfo as? Dictionary<String,String> {
                        if let s = info["name"] {
                            if(name==s){//name is the the one you want cancel
                                notifyCancel = notify
                                break
                            }
                        }
                    }
                }
            i++
            }
            

            【讨论】:

            • 不需要while,如果让通知,只需用for notify in notifyArray as [UILocalNotification] { if let info = notifier.userInfo as? Dictionary&lt;String,String&gt; {...}}保持简短
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多