In the previous article we walked through implementing the new iOS 7 multitasking feature called background app fetch, which is great way for your app to periodically launch in the background and update its content in order to keep the app fresh for the user - and the best part is that it's adaptive, meaning it updates based on when the user launches your application. If you haven't had a chance to read that article, I suggest you give it a look to see how you can build this feature into your app. In this article, we will continue our exploration of new iOS 7 multitasking features with Remote Notifications, which allow your app to launch immediately whenever you send it a special push notification - it can even launch your app in the background with a silent remote notification, which will not bother the user.
How does it work?
A remote notification is a push notification with the content-available flag set. A silent notification would contain no alert or sound and would be used only to trigger background work. You are then free to choose what to do when that background work concludes. For example, you can update the UI, or post a local notification.
If an App uses too many remote notifications that pop-up too many notification banners, we know as users that we may turn-off notifications for that bothersome, chatty app. Because users cannot determine if they are receiving too many silent notifications (since they can't see them by definition) then they cannot manage them and are unaware that a certain app is sending too many silent notifications. Because of this, Apple thought it would be a good idea, for the sake of the battery, to throttle the number of silent notifications. In other words, remote notifications are rate limited and Apple protects the device by limiting the push rate. So, have no fear of sending too many. Send as many as you need - you won't get into any trouble.
Prerequisite: APNS Set-up
In order to follow the step-by-step in this article, you'll need to set-up Apple Push Notification Services (APNS) in the app, on the Apple Developer website for the app, and then select a push provider. If you have not done this before, budget some time to work through a handful of steps that you'll need to take in order to establish push notifications across the board. If you have not done this before, this is the hardest part.
The first step in this set-up is for you is to select a push provider. Once you are in production, a provider will typically charge you once you send greater than 1 Million push notifications in a one month period. Hopefully, you'll have a business model for your app by the time you go big. In the meantime, for development, I suggest one of the following:
1. Urban Airship - as one of the original and most popular push notification platforms this one is definitely worth a look,
2. Parse - an awesome service that was acquired by Facebook as part of its "march into mobile" has lowered its price, is dead simple, and is pay-as-you-go.
Both of these services are essentially free for development, with comfortable ceilings that should suffice any amount of development testing.
3. You can also send push notifications from your command line with a tool called Houston which is written in Ruby and installed as a gem.
I use Parse for development, and it is what I used in the sample code, but do take a look at each of the above, or find your own, and select the one that best suites you and your needs.
Whichever provider you select will determine the APNS set-up steps you take and each has excellent documentation on setting up the provisioning profile and certificate for your app id, enabling push notifications from the developer portal, integrating their SDKs and their required libraries, and updating your build settings. If you work with Urban Airship or Parse you can use the same infrastructure for production. If you work with Houston you can get started faster but will need to come back and evaluate your infrastructure for production support. Once you've successfully set-up a provider and tested it you are now ready to follow the two step remote notification walk-through. I have provided the sample project which is posted on GitHub that you can use as a reference to follow along step-by-step.
The Step By Step:
1. First, I created an iPhone Single View Application and enabled Remote Notifications in Xcode's Project Editor / Capabilities tab by switching Background Modes to ON and then checking off Remote Notifications.
2. I verified that Push Notifications from my provider worked by sending my push notification enabled app a push notification:
I added the new application:didReceiveRemoteNotification:fetchCompletionHandler: iOS 7 application delegate method that is called when a silent notification is received:
Because you cannot test Push Notifications in the Simulator I save a @"Silent" string value to NSUserDefault to ensure the silent notification delegate is called and that I am receiving the silent notification. Then I sent a Push Notification payload message from Parse with the following JSON:
Making sure the app is in the background I loaded the NSUserDefault field from the ViewController to ensure that the message was received and actioned in the AppDelegate.
And that's it! Now, you have added the framework to your application to implement remote notifications in order to wake up your app and have an immediate action. You'll need to pass the completionHandler to your specific data fetching methods in your real-world app and then call the completion handler when you've processed the data and updated your UI. I simply update NSUserDefaults in the sample and then load from my ViewController to keep things simple.
Where to Next:
If you've enjoyed this article and want to dive deeper into multitasking topics in iOS I recommend David Chan's WWDC 2013 Session 204: What's New With Multitasking (keeping content fresh and interesting).
Also, check out Steve Algernon's WWDC 2013 Session 705: What's New in Foundation Networking, which is the best session on the new NSURLSession (see what he did there - btw this is Steve's joke - not mine). NSURLSession is the replacement for the decade old NSURLConnection, introduced in iOS 7 and OS X 10.9 Mavericks, that allows out of process background transfers and is the future of networking in Foundation.
For an introduction to notifications and push architecture in general check out the now classic Darryl Bleau, James Callender (iOS), and Jason Thorpe (OS X) WWDC 2011 Session 517: Using Local and Push Notifications (On iOS and Mac OS X).
In the next article we'll explore Background Transfer Service, which allows you to enqueue large uploads and downloads for iOS to continue in the background not only after your user leaves your app but even after they reboot the device.
Now go off and add remote notifications in your killer app.