简体   繁体   中英

cancelLocalNotification doesn't seem to work

In the following code I check whether the current task (the one being edited) has a localNotification. If so, I try to cancel that notification. Then (if the fireDate hasn't already passed) I update the alertBody of the notification with the (possibly) changed information and re-schedule it.

The problem is that if I create a notification and then edit it, I end up with two notifications going off. Somehow the original one isn't getting canceled...

if ([currentTask localNotification])
{
    [[UIApplication sharedApplication] cancelLocalNotification:[currentTask localNotification]];
    if ([[NSDate date] compare:[currentTask localNotification].fireDate] == NSOrderedAscending)
    {
        NSLog(@"current task name: %@", [currentTask name]);
        NSString *temp = [NSString stringWithFormat:@"Alert:\n%@", [currentTask name]];
        [[currentTask localNotification] setAlertBody:temp];
        [[UIApplication sharedApplication] scheduleLocalNotification:[currentTask localNotification]];
    }
    else
        [currentTask setLocalNotification:nil];
}

Any insights as to the problem here?

I know that a copy is made of the notification when it's scheduled - how does cancelLocalNotification find the correct copy? Does it do it by testing the properties for equality? Or does it make a copy of the pointer address and match that up? In other words, if one of the properties is changed, will cancelLocalNotification not be able to match it with the notification that was originally scheduled?

I'll add my findings here for iOS 9. Previously I had code that went like so:

UILocalNotification* notification = getNotification();
[[UIApplication sharedApplication] cancelLocalNotification: notification];
notification.alertBody = newBody;
[[UIApplication sharedApplication] scheduleLocalNotification: notification];

Worked great before iOS 9, cancelling the existing instance and then rescheduling it with a new alertBody or soundName. Then along comes iOS 9 and suddenly running this code doesn't actually cancel the previous notification and so I was ending up with more notifications than I wanted!

The fix for me was to not be lazy in reusing the old notification so I now create a new notification and populate it with the fields of the old notification. Works a treat!

EDIT: I still seem to be getting problems with [[UIApplication sharedApplication] cancelLocalNotification: notification] not working in other situations... I've got my notifications automatically repeating themselves every minute and it seems there might be a bug in Xcode 7.0 meaning its sometimes ignored: https://forums.developer.apple.com/thread/9226

EDIT II: Looks like repeating local notifications scheduled in the app before it was built against iOS 9 can't be cancelled.. at least not easily... still working on finding a solution to this as my app is centered around repeating local notifications for reminders!

EDIT III: I've managed to get rid of a lingering, un-cancellable notification by force quitting the app after an attempt to cancel it... and that seems to have worked... it's not a great solution, certainly not something I want to get my users to do if there's some kind of alternative... I've posted a separate question to see if anyone has any further ideas.

I came across the same issue. the solution i used was.

// Sort the notification on the fire date of the notification.
NSSortDescriptor * fireDateDesc = [NSSortDescriptor sortDescriptorWithKey:@"fireDate" ascending:YES];

//get all scheduled notifications.
NSArray * notifications = [[[UIApplication sharedApplication] scheduledLocalNotifications] sortedArrayUsingDescriptors:@[fireDateDesc]];

// Cancel all scheduled notifications.
[[UIApplication sharedApplication] cancelAllLocalNotifications];

for (int i=0; i<[notifications count]; i++){

    UILocalNotification* oneEvent = [notifications objectAtIndex:i];

    // update notification data here an then schedule the notification.

    [[UIApplication sharedApplication] scheduleLocalNotification:oneEvent];

}

Canceling UILocalNotifications one by one to update something in the notification produces an issue that sometimes the notification does not get cancelled.

So the solution i have implemented is:

1: get all scheduled notifications and store them in whatever you like.

2: Then cancel all scheduled notifications.

3: From step one loop through the notifications, update whatever you want and schedule notifications on the go.

hope this helps.

It looks like if any of the properties of a UILocalNotification have been changed since it was scheduled, that cancelLocalNotification won't work. That makes me think that cancelLocalNotification must check equality of the different properties against the currently scheduled copies of notifications to see which one is a match.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM