I am trying to setup a UILocalNotification
to run every 30 seconds using the following logic, however it seems to be misbehaving. There are 2 issues:
- When the notifications get fired there seems to be a lot of them all at once, rather than 1 every 30 seconds.
- The application icon badge number doesn't seem to increase. It just stays at 1.
Please can someone help me work out what I've done wrong?
// Create 'base' notification we can use
UILocalNotification *baseNotification = [[UILocalNotification alloc] init];
baseNotification.timeZone = [NSTimeZone defaultTimeZone];
baseNotification.repeatInterval = NSMinuteCalendarUnit;
baseNotification.alertBody = @"My Message.";
baseNotification.alertAction = @"My Alert Action";
baseNotification.soundName = UILocalNotificationDefaultSoundName;
UILocalNotification *alertOne = [baseNotification copy];
alertOne.applicationIconBadgeNumber++;
alertOne.fireDate = [[NSDate date] dateByAddingTimeInterval:30];
[[UIApplication sharedApplication] scheduleLocalNotification:alertOne];
UILocalNotification *alertTwo = [baseNotification copy];
alertTwo.applicationIconBadgeNumber++;
alertTwo.fireDate = [[NSDate date] dateByAddingTimeInterval:60];
[[UIApplication sharedApplication] scheduleLocalNotification:alertTwo];
There is currently no way possible to achieve custom repeats with intervals.
However, the notification system can queue up to 64 notifications so the closest thing you could do is to manually set as many notifications as you need (with each one having a different number for the badge and a different fireDate) and then have your notifications list updated by setting new ones when you're running low on them.
This will return how many notifications you've in queue:
[[[UIApplication sharedApplication] scheduledLocalNotifications] count]
There's also this post that I would recommend you reading for further help:
iOS badge number live update
Good luck!
Try this one.
UILocalNotification *baseNotification = [[UILocalNotification alloc] init];
baseNotification.timeZone = [NSTimeZone defaultTimeZone];
baseNotification.repeatInterval = NSMinuteCalendarUnit;
baseNotification.alertBody = @"My Message.";
baseNotification.alertAction = @"My Alert Action";
baseNotification.soundName = UILocalNotificationDefaultSoundName;
UILocalNotification *alertOne = [baseNotification copy];
alertOne.fireDate = [[NSDate date] dateByAddingTimeInterval:30];
alertOne.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1;
UILocalNotification *alertTwo = [baseNotification copy];
alertTwo.fireDate = [[NSDate date] dateByAddingTimeInterval:60];
alertTwo.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1;
Regarding second point, you're increasing the badge number of the copy not the original notification. And since the original has a zero badge number you'll always get a copy with zero badge number too and increasing it will make it always 1.
The solution is to increase the badge of the original notification right before making the copy:
...
baseNotification.applicationIconBadgeNumber++;
UILocalNotification *alertOne = [baseNotification copy];
alertOne.fireDate = [[NSDate date] dateByAddingTimeInterval:30];
[[UIApplication sharedApplication] scheduleLocalNotification:alertOne];
baseNotification.applicationIconBadgeNumber++;
UILocalNotification *alertTwo = [baseNotification copy];
alertTwo.fireDate = [[NSDate date] dateByAddingTimeInterval:60];
[[UIApplication sharedApplication] scheduleLocalNotification:alertTwo];
According NSObject class reference :
copy - Returns the object returned by copyWithZone:
And copyWithZone returns a shallow copy.
So its like all notification have same properties .
Hence , badge number is always "1" and fireDate is same for all notifications. i.e. last one that you apply .
Hence , notifications get fired at same time.
Hope , it helps.
I think you get a lot of notifications every 30 seconds is because you did not cancel previous notifications. Add this line at the top of your code.
[[UIApplication sharedApplication] cancelAllLocalNotifications];