2010-07-01 4 views
47

У меня проблема с моей UILocalNotification.Отмена 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 я должен удалить?
Есть ли способ перечислить все уведомления?

Единственное, что у меня есть, это идентификатор напоминания, который я должен удалить.
Я думал о том, чтобы сохранить объект UILocalNotification в моем объекте «Примечание» и получить его таким образом, а когда я сохраняю в базу данных SQLite сериализацию объекта и т. Д. ... есть ли более разумный способ?

ответ

57

Вы можете получить список всех запланированных уведомлений от scheduledLocalNotifications или вы можете отменить их все:

[[UIApplication sharedApplication] cancelAllLocalNotifications]; 
+2

Я знаю о cancelAllLocalNotifications, но я просто хочу, чтобы отменить конкретный. ScheduledLocalNotifications, возможно, выполнит эту работу ... Я попробую. – f0rz

+1

Забыл сказать, это действительно сработало! :) – f0rz

+1

вы можете поделиться как? – Wasim

13

Мое решение для архивирования UILocalNotification объект, который вы запланировали с NSKeyedArchiver и хранить его где-нибудь (в PLIST является предпочтительно). И затем, когда вы захотите отменить уведомление, посмотрите на plist для получения правильных данных и используйте NSKeyedUnarchiver для разблокировки. код довольно легко:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:notice]; 

и

UILocalNotification *notice = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 
+0

Вы также можете сериализовать NSData из archishedDataWithRootObject с кодировкой Base64, а затем сохранить в объект JSON, который у вас уже есть. –

+0

@ RafaelSanches извините за нитку. Но в чем преимущество использования объекта JSON, если целью является сохранение/получение uilocalnotification для последующего удаления? – iamdavidlam

6

Мое решение вам, когда вы создаете UILocalNotification в то время вы создаете один NSMutableDictionary и хранить это уведомление в качестве значения для ключа как ваш ID и положите это NSMutableDictionay на ваш NSUserDefaults

Итак, когда вы хотите отменить какое-либо конкретное локальное значение в это время, вы пишете [dictionary valueforkey @"KEY"], где в качестве ключа вы передаете свой идентификатор, так что вы получите, что конкретное местное уведомление и передать его в

[[UIApplication sharedApplication] scheduleLocalNotification:localNotif]; 
91

Моего решения заключается в использовании UILocalNotificationUSERINFO словаря. На самом деле то, что я делаю, это генерировать уникальный идентификатор для каждого из моих уведомлений (конечно, это 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]; 

Я не знаю, если этот подход лучше или нет по отношению к Архивирование/Unarchving один, однако он работает и данные пределы будут сохранены только идентификатор.

Edit: был отсутствующий Braket

+0

Я пробовал ваш метод и не работал для меня. не могли бы вы сказать мне, что случилось? http://stackoverflow.com/questions/9139586/cancel-local-notification-not-working – Farini

+2

Вы не используете мой метод в своем решении. Мое решение проходит вокруг идентификатора, в то время как вы используете весь объект. Кажется, из вашего кода есть ранний dealloc объекта уведомления, и именно поэтому «непризнанный селектор» (обычно это происходит, когда старое местоположение объекта было повторно использовано другим видом объекта). Попытайтесь получить имя класса объекта непосредственно перед отправкой сообщения cancelNotification, чтобы его выкопать, это может помочь в отладке. Кроме того, когда вы назначаете «TheNotification», используйте «self.theNotification = ...«вместо« theNotificaiton = ... » – viggio24

+0

Большое вам спасибо! Вы на самом деле вдохновили меня добавить кнопку в каждую ячейку, где я могу: cancelLocalNotification atindex [sender tag], и она работает намного лучше, чем с uialertview. сказал, что имя объекта сейчас перед отменой, и оно отлично работает! – Farini

0

Мое решение удалить все запланированные уведомления об этих методах.

-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. Затем это помогает перейти в нужное место в приложении.

0

Спасибо @ 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++ 
} 
+0

Не нужно вовремя, и если сообщите об этом, просто сохраните его с помощью 'для уведомления в notifyArray как [UILocalNotification] {if let info = notifier.userInfo as? Словарь {...}} ' –

1

Swift версия для отмены конкретного "Local Notification" с использованием UserInfo .:

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

В быстры, вы сначала добавить a 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) 
       } 
      } 
     } 
    } 
} 
+0

Примечание: UIApplication.sharedApplication() теперь UIApplication.shared –

Смежные вопросы