问题 UILocalNotifications和applicationIconBadgeNumber的良好模式


我的应用程序安排UILocalNotifications在用户选择的不同时间交付给其用户。

我遇到了如何在这种情况下管理applicationIconBadgeNumber的情况。

我们知道,您必须在创建通知时设置徽章编号。我的问题是徽章数量的状态可以随时改变。考虑这种情况:

1)用户获得3个通知。

2)用户创建新通知以在将来的给定时间点提醒她。此通知的值为1加上应用程序徽章的当前值(3)。

3)用户开展业务。在他们的业务过程中,他们通过查看或以其他方式使用应用程序清除他们当前拥有的所有3个通知(以及徽章编号)。

4)经过给定的时间后,通知将显示在iOS中,以及之前计算的值(如果您不记得,则为4)。

5)即使用户只有一个实际通知,应用程序徽章现在也是4。

我上下搜索过,但我找不到这个问题的答案,几乎肯定有一个简单的答案,我完全不知道了。我该如何解决这个困境?


6297
2017-12-06 02:56


起源



答案:


由于您的应用程序将来无法查看,并知道您将立即处理哪些事件,以及哪些事件将暂时“待决”,因此需要做一些诀窍:

当您的应用处理通知时(通过点击通知,图标,...),您必须:

  1. 获取所有待处理通知的副本
  2. '重新编号'这些待处理通知的徽章编号
  3. 删除所有待处理的通知
  4. 使用更正后的徽章重新注册通知副本 数字了

此外,当您的应用注册新通知时,它必须首先检查有多少通知待处理,并使用以下内容注册新通知:

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];
        }
    }
}

归功于@Whassaahh


15
2017-12-06 04:36



这很棒。我只是想验证实现这一目标的唯一方法是非常混乱;) - dclowd9901


答案:


由于您的应用程序将来无法查看,并知道您将立即处理哪些事件,以及哪些事件将暂时“待决”,因此需要做一些诀窍:

当您的应用处理通知时(通过点击通知,图标,...),您必须:

  1. 获取所有待处理通知的副本
  2. '重新编号'这些待处理通知的徽章编号
  3. 删除所有待处理的通知
  4. 使用更正后的徽章重新注册通知副本 数字了

此外,当您的应用注册新通知时,它必须首先检查有多少通知待处理,并使用以下内容注册新通知:

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];
        }
    }
}

归功于@Whassaahh


15
2017-12-06 04:36



这很棒。我只是想验证实现这一目标的唯一方法是非常混乱;) - dclowd9901