Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good pattern for UILocalNotifications and applicationIconBadgeNumber

My app schedules UILocalNotifications to be delivered to its users at varying times of the user's choice.

I'm running into a situation with how to manage the applicationIconBadgeNumber in this scenario.

As we know, you have to set the badge number at the time you create the notification. My problem is that the state of the number of badges can change at any time. Consider this scenario:

1) User gets 3 notifications.

2) User creates a new notification to alert her at a given point of time in the future. This notification carries the value of 1 plus the current value of the application badge (3).

3) User goes about their business. In the process of their business, they clear all 3 notifications (and, thus, badge numbers) they currently have by viewing them or otherwise using the app.

4) After the given amount of time passes, the notification appears in iOS, along with its previously calculated value (4, if you don't remember).

5) The application badge is now, 4 even though the user only has one actual notification.

I have searched up and down, but I cannot find an answer to this question which almost certainly has a simple answer I'm completely missing. How do I solve this quandary?

like image 280
dclowd9901 Avatar asked Dec 06 '13 02:12

dclowd9901


1 Answers

Since your app cannot look in the future, and know which events you'll handle immediately, and which ones you'll leave 'pending' for a while, there's some trick to do :

When notifications are handled by your app (by tapping on the notification(s), icon, ...), you have to :

  1. get a copy of all pending notifications
  2. 'renumber' the badge number of these pending notifications
  3. delete all pending notifications
  4. re-register the copy of the notifications with their corrected badge numbers again

Also, when your app registers a new notification, it has to check how many notifications are pending first, and register the new notification with with :

badgeNbr = nbrOfPendingNotifications + 1;

Looking at my code, it will get clearer. I tested this, and it's definitely working :

In your 'registerLocalNotification' method you should do this :

NSUInteger nextBadgeNumber = [[[UIApplication sharedApplication] scheduledLocalNotifications] count] + 1;
localNotification.applicationIconBadgeNumber = nextBadgeNumber;

When you handle the notification (appDelegate), you should call the method below, which clears the badge on the icon and renumbers the badges for pending notifications (if there are any)

Note that the next code works fine for 'sequential' registered events. If you would 'add' events in between pending ones, you'll have to 're-sort' these events first. I didn't go that far, but I think it's possible.

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

Credits to @Whassaahh

like image 110
Toseef Khilji Avatar answered Nov 15 '22 22:11

Toseef Khilji