我已经找到、实施并测试了一个“解决方法”,用于(显然)自动增加应用程序图标的徽章编号,该方法适用于非重复的本地通知
UILocalNotifications 确实不可能让 iOS 在触发多个本地通知时“自动”更新/增加徽章编号,并且用户“忽略”它们或不立即处理它们,因此它们“堆积”在通知中中心。
此外,向您的应用程序“添加一些回调方法”无法处理“自动增量”,因为整个通知事情是由 iOS 在您的应用程序“外部”处理的,您的应用程序甚至不需要运行。
但是有一些解决方法,这是基于我通过实验发现的知识,因为 XCode 文档对徽章属性过于模糊。
- 徽章只是一个“整数”,实际上更像是在注册通知之前分配给 applicationIconBadgeNumber 属性的“虚拟标签”。你可以给它任何值——当通知触发时,iOS 会将该值添加到徽章中,无论你在注册通知时设置什么值。iOS 没有神奇的“自动增量”或其他操作(可能与推送通知不同,但这不是这里的主题)。iOS 只是从注册的通知中获取数字(整数),并将其放入徽章中。
因此,对于“解决方法”,您的应用程序必须已经为它新创建的每个通知提供正确的、递增的徽章编号,并在“待处理通知之上”注册。
由于您的应用程序无法查看未来,并且知道您将立即处理哪些事件,以及哪些事件您将“等待”一段时间,因此有一些技巧可以做:
当您的应用程序处理通知时(通过点击通知、图标等),您必须:
- 获取所有待处理通知的副本
- “重新编号”这些待处理通知的徽章编号
- 删除所有待处理的通知
- 再次使用更正的徽章编号重新注册通知副本
此外,当您的应用注册新通知时,它必须首先检查有多少通知处于待处理状态,然后使用 with 注册新通知:
badgeNbr = nbrOfPendingNotifications + 1;
查看我的代码,它会变得更清晰。我对此进行了测试,它肯定有效:
在您的“registerLocalNotification”方法中,您应该这样做:
NSUInteger nextBadgeNumber = [[[UIApplication sharedApplication] scheduledLocalNotifications] count] + 1;
localNotification.applicationIconBadgeNumber = nextBadgeNumber;
当您处理通知(appDelegate)时,您应该调用下面的方法,该方法清除图标上的标记并重新编号待处理通知的标记(如果有)
请注意,下一个代码适用于“顺序”注册事件。如果您要在未决事件之间“添加”事件,则必须首先“重新排序”这些事件。我没有走那么远,但我认为这是可能的。
- (void)renumberBadgesOfPendingNotifications
{
// clear the badge on the icon
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
// first get a copy of all pending notifications (unfortunately you cannot 'modify' a pending notification)
NSArray *pendingNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
// if there are any pending notifications -> adjust their badge number
if (pendingNotifications.count != 0)
{
// clear all pending notifications
[[UIApplication sharedApplication] cancelAllLocalNotifications];
// the for loop will 'restore' the pending notifications, but with corrected badge numbers
// note : a more advanced method could 'sort' the notifications first !!!
NSUInteger badgeNbr = 1;
for (UILocalNotification *notification in pendingNotifications)
{
// modify the badgeNumber
notification.applicationIconBadgeNumber = badgeNbr++;
// schedule 'again'
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
}
}
要真正做到“防弹”,此方法应该是“原子”(内核)代码,防止 iOS 在此方法执行期间触发通知。我们必须在这里冒这个险,发生这种情况的可能性很小。
这是我对 Stackoverflow 的第一个贡献,因此如果我不遵守此处的“规则”,您也可以发表评论