取消本地通知似乎无效。

3
在以下代码中,我检查当前任务(正在编辑的任务)是否有一个本地通知。如果有的话,我会尝试取消该通知。然后(如果fireDate还没有过去),我会更新通知的alertBody,并重新安排它。
问题是,如果我创建了一个通知然后进行编辑,最终会有两个通知被触发。某种方式原始通知没有被取消...
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];
}

这里有什么问题的见解吗?

我知道在计划通知时会复制一份 - cancelLocalNotification是如何找到正确的副本的呢?它是通过测试属性是否相等来实现的吗?还是它会复制指针地址并进行匹配?换句话说,如果其中一个属性被更改,cancelLocalNotification是否无法将其与最初计划的通知匹配?


我认为您需要取消现有的通知,然后创建一个全新的通知并安排它。 - random
问题不在于创建另一个通知,而在于取消原始通知。 - user3818237
你是否正在从磁盘加载本地通知?很可能你没有得到正确的指针来取消现有的通知。 - random
这些任务被存储在一个数组中。每个任务都存储了它自己的通知(如果有的话)。 - user3818237
3个回答

2
我会将我在iOS 9上的发现添加到这里。之前我的代码是这样的:
UILocalNotification* notification = getNotification();
[[UIApplication sharedApplication] cancelLocalNotification: notification];
notification.alertBody = newBody;
[[UIApplication sharedApplication] scheduleLocalNotification: notification];

在iOS 9之前,使用新的alertBody或soundName取消现有实例,然后重新安排它可以很好地工作。但是,iOS 9出现后,运行此代码实际上并没有取消以前的通知,因此我得到了比想要的更多的通知!对我来说,解决方法是不懒惰于重用旧通知,因此我现在创建一个新通知,并用旧通知的字段填充它。效果很好!编辑:在其他情况下,[[UIApplication sharedApplication] cancelLocalNotification:notification]似乎仍然存在问题...我的通知每分钟自动重复一次,似乎Xcode 7.0中可能存在错误,因为有时会被忽略:https://forums.developer.apple.com/thread/9226 编辑II:看起来在应用程序构建为iOS 9之前,安排的重复本地通知无法取消...至少不容易...仍在寻找解决方案,因为我的应用程序围绕着重复本地通知提醒!
编辑 III:我尝试取消一个无法取消的通知,然后在强制退出应用程序后成功摆脱了它......似乎这样做起作用了......这不是一个好的解决方案,如果有其他可行的方案,我肯定不想让我的用户这样做...我已经发布了一个单独的问题,看看是否有人有更多的想法。

1
我发现了同样的问题。我使用的解决方案是:
// 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];

}

取消单个 UILocalNotifications 以更新通知中的某些内容会导致有时通知无法被取消。因此,我实现的解决方案是:
1. 获取所有已安排的通知并将它们存储在您喜欢的任何地方。
2. 然后取消所有已安排的通知。
3. 从第一步开始循环遍历通知,更新您想要的任何内容,并在使用过程中安排通知。
希望这可以帮助到您。

谢谢!对于可能相关的人:如果您只想取消(而不是更新)特定通知,则需要在循环内跳过它。 “userInfo”字段对于唯一标识个别通知非常有用。 - Andy Weinstein

0

看起来如果 UILocalNotification 的任何属性自它被安排以来已被更改,那么 cancelLocalNotification 将不起作用。这使我想到 cancelLocalNotification 必须检查不同属性的相等性,以确定当前安排的通知副本中哪一个与其匹配。


我认为在某些情况下可能会出现这种情况...我正在取消通知,稍微编辑实例,然后重新安排,这会导致重复的通知,因为取消失败了。但是话说回来,在iOS 9上,如果通知已经被安排了一段时间,cancelLocalNotification似乎就不想工作(在快速测试中创建通知,让它重复几次,然后取消它可以正常工作)。在那种情况下似乎有帮助的是在取消通知后强制退出应用程序... - CMash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接