Have you ever wanted to have your app give a notification when it is not open, but don’t have a web backend? That’s where UILocalNotification comes in.
One caveat, UILocalNotification cannot open your app (at least as far as I know), so it can only run at pre-programmed times, but that is still useful in many situations.
An example use of UILocalNotification
UILocalNotification is pretty simple to setup in the simplest cases. Below is an example of one I used:
- (void) createMyNotifications
{
[[UIApplication sharedApplication] cancelAllLocalNotifications];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.day = 31;
comps.month = 12;
comps.year = 2013;
NSDate * nextAlertTime = [[NSCalendar currentCalendar] dateFromComponents:comps];
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = nextAlertTime;
notification.timeZone = [NSTimeZone systemTimeZone];
notification.alertBody = nil;
notification.soundName = nil;
notification.applicationIconBadgeNumber = 28;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
So let’s unpack this. First off, just in case my program still had some notifications left in the buffer that I now want to invalidate, I use [[UIApplication sharedApplication] cancelAllLocalNotifications] . That is just a message to my application itself to cancel its notifications.
After that, I need a date to tell the alert when to happen. If you recognize that code, you should, because it is taken pretty much directly from my post “Displaying a human readable NSDate”, with a changed name for the NSDate object.
Next we create the UILocalNotification. Nothing special needs to be done at this step, so just use a vanilla [[alloc] init].
Now things get interesting. First we set the notification’s “fireDate” property to that NSDate we made earlier. After that, we have to set the “timeZone” property to denote what timeZone that NSDate was set in. This is a bit confusing to me, and I might change this in my app soon, but according to the apple documentation for the timeZone property:
The date specified in
fireDate
is interpreted according to the value of this property. If you specifynil
(the default), the fire date is interpreted as an absolute GMT time, which is suitable for cases such as countdown timers. If you assign a validNSTimeZone
object to this property, the fire date is interpreted as a wall-clock time that is automatically adjusted when there are changes in time zones; an example suitable for this case is an an alarm clock.
So, since my program is actually a countdown timer, I should probably change this to nil for my program. If yours is more like an alarm clock, you should probably set the appropriate timezone it was set in.
Next we start setting what we want the user to see. In this case, I just want to update the application badge number, so I set the other two things to nil. So in this case, to set the badge, we just set the applicationIconBadgeNumber property. Now there other two are useful in other situations. The “alertBody” takes an NSString, and this is what is printed in the notification. This I believe shows up in the Notification center, as well as the text that you show as the notification in the banner or alert view, whichever the user has set in their notification center preferences in the Settings app.
The soundName property is where you could tell it to play a sound when this UILocalNotification is triggered. The default should be nil (no sound), but I wanted to make it obvious that such was my intent. You could use the default chime sound with UILocalNotificationDefaultSoundName. If you have your own, and it is included in the bundle, you can just put its name in there with extension, like @”someSound.mp3″.
Finally, we have finished constructing our notification, and now we simply schedule it with [[UIApplication sharedApplication] scheduleLocalNotification:notification]. Pretty simple.
A note about applicationIconBadgeNumber
As mentioned earlier, this cannot wake up your app, at least that I know, so you have to preprogram things. So say you wanted to game, and you wanted to notify the user that there are 5 things to attend to in your app that are added on some interval, like every 2 hours. In this case, you would have to set up 5 different notifications, each with their NSDates 2 hours apart, and set the notifications manually to whatever badge number you wanted. It would be nice if it could wake up the app and do some processing if needed, but currently it cannot. Push notifications can, and if we work more with the Background Modes added in iOS7 we might, but I have not worked with either of these yet.
I hope you found this article helpful. If you did, don’t hesitate to share this post on twitter or your social media of choice. The blog is still pretty new, and every share helps. Of course, if you have any questions, don’t hesitate to contact me on twitter @CodingExplorer, and I’ll see what I can do. Thanks!