2

I'm using UILocalNotifications in my app. Sometimes I schedule a repeating notification and sometimes a non-repeating notification. Whenever a notification fires I want to increment the app badge number. So I do localNotification.applicationIconBadgeNumber = badgeNumber; this works fine... except when the notification is a repeating notification because if I have previously set a repeating notification with badge number 1, then I set another non-repeating notification with badge number 2.

Flow is this:

Notification 1 fires (first time) - Badge number = 1 (OK!) 
Notification 2 fires              - Badge number = 2 (OK!) 
Notification 1 fires (repeating)  - Badge number = 1 (ERROR)

As you understand when notification 1 fires again I still want the app badge number to be displaying 2 (for 2 missed notifications). Can I possibly achieve this behaviour? Or is there something obvious that I have missed? For me the more logical badge behaviour for a repeating notification would be that it for the first time sets the badge number and for subsequent times it will not change the badge number.

Peter Warbo
  • 11,136
  • 14
  • 98
  • 193
  • Here's a possible workaround : http://stackoverflow.com/a/15461328/1869369 using push notifications is not necessary – Ronny Webers Mar 17 '13 at 13:46

4 Answers4

1

Simple: I'm sorry, Dave. I'm afraid I can't do that.

There is no way to let the badge count stay at the "highest" count as you want it to be when using a UILocalNotification.

The badge count will always be set to the value that was set by you when scheduling the notification (as you already know). You can not assume that the user will open your application whenever he receives a notification, so updating the badge count for already scheduled notifications (repeating and non-repeating) on each app launch would not work for sure and wouldn't be an option.

The only way you could do it would be by using Push Notifications instead, keep track of all "unread" notifications on your server and mark the notifications as "read" on your server as soon as the user launches your app.

Björn Kaiser
  • 9,882
  • 4
  • 37
  • 57
  • Actually I think you are wrong there, it is indeed possible to keep track of all notifications, it's a simple as when the app goes in to background you check how many notifications you need to create and then you schedule them. And for each notification you increment the `applicationIconBadgeNumber` this works very well for non-repeating notifications. But the issue ocurrs when it's a repeating notification which I have tried to explain in my question. – Peter Warbo Jan 09 '13 at 19:34
  • But then you would have to update the badge count for all scheduled notifications on each launch of the application. Assume you schedule 20 notifications, you set the badge count from 1...20. Three notifications are fired, badge count is at 3, user opens the app, and you reset the badge count as a good developer in that case. Then you have to update the badge counts for notification 4...20? that does not sound like good practice to me however it would solve the issue for non-repeating notifications. – Björn Kaiser Jan 09 '13 at 19:39
  • In my case each badge number represents an object which is overdue, so just because the user opens the app does not mean that I should reset the app badge (the objects are still overdue if the user opens the app). – Peter Warbo Jan 09 '13 at 19:45
  • "You can not assume that the user will open your application whenever he receives a notification" - I'm aware of that. "so updating the badge count for already scheduled notifications (repeating and non-repeating) on each app launch would not work for sure and wouldn't be an option" - Updating badge count on app launch is not the issue here... – Peter Warbo Jan 09 '13 at 19:59
1

I suppose the only way to deal with having repeated notifications and also have it increment the app badge number the first time it's fired is to schedule your repated notification without badge number like:

UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:60];
localNotification.alertBody = @"1";
localNotification.alertAction = @"Send";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.repeatInterval = NSMinuteCalendarUnit;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];

And then schedule a notification which only sets the app badge number at the same time the repeated notification is fired for the first time:

UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:60];
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = 1;
localNotification.hasAction = NO;
localNotification.alertBody = nil;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
Peter Warbo
  • 11,136
  • 14
  • 98
  • 193
0

You can simply do it using a if condition like:

- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)localNotification
{
   if([UIApplication sharedApplication].applicationIconBadgeNumber < localNotification.applicationIconBadgeNumber)
   {
      [UIApplication sharedApplication].applicationIconBadgeNumber = localNotification.applicationIconBadgeNumber;
   }
}

(Didn't checked the above code).

Midhun MP
  • 103,496
  • 31
  • 153
  • 200
  • You need to set the app badge number through the local notification like `firstLocalNotification.applicationIconBadgeNumber = 1` `secondLocalNotification.applicationIconBadgeNumber = 2` – Peter Warbo Jan 09 '13 at 18:49
  • ya, i'm doing that. First checks whether the applications badge number is less than currently triggered notifications badge number. If yes then I set that as applicaion's badge number. If not it means it's a repeated notification. – Midhun MP Jan 09 '13 at 18:52
  • I don't understand really what you're saying. Can you show full code for this? – Peter Warbo Jan 09 '13 at 18:56
  • Aha, no sorry that doesn't solve my problem. I want the app badge number to increment when app is in background. – Peter Warbo Jan 09 '13 at 19:22
0

In my app I've had to add badge number using repeating local notifications. And every time user open the app badge number should be reseted. As result all scheduled notifications should recalculate badge number.

func applicationDidEnterBackground(application: UIApplication) {
    addBadgeNumberToScheduledNotifications()
}

func addBadgeNumberToScheduledNotifications() {
    var badgeNumber: Int = 0
    UIApplication.sharedApplication().applicationIconBadgeNumber = 0
    if let notifications = UIApplication.sharedApplication().scheduledLocalNotifications {
        UIApplication.sharedApplication().cancelAllLocalNotifications()
        for notification in notifications {
            notification.applicationIconBadgeNumber = notification.fireDate > NSDate() ? ++badgeNumber : 0
            UIApplication.sharedApplication().scheduleLocalNotification(notification)
        }
    }
}
Alex
  • 35
  • 6