This article is based on iPhone and iPad in Action, published on August, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]
Preparing your application to use push notifications
Introduction
Leave it to Apple to make the preparation more complex than the coding. You will find that more time is spent on creating an uploading the signing certificates than actually writing the code to receive the push notifications. We will explain how. Let’s begin by setting up the signing certificates.
Setting up your application certificate
The first thing to note is that you must have a valid Apple developer account to test push notifications. We will be showing you how to generate two items that are required. The first item we will be generating is a special provisioning profile. This profile will be used to sign the application when deploying it to your iPhone. The second is a client SSL certificate. The push provider will use this to establish a connection with Apple’s push notification servers.
Start by logging into your Apple developer account. Once you have logged in, open up the program portal and navigate to the App IDs tab. If you haven’t already done so, you will need to add your application bundle identifier to this list. The format for this should be reverse domain. An example of this might be com.rightsprite.pushtest. Make sure that you don’t use any wildcards because the system must be able to uniquely identify your application.
Once you have added your application, you must now configure it to receive push notifications. You have the option to configure the app for development as well as production. It is always good practice to use the development certificate when testing and switch to the production one when you are ready to submit to the app store. Figure 1 shows what this section should look like.
Figure 1 Configuring the app to receive push notificationsAfter pressing the Configure button, the following screen gives you the option to configure either the development or the production certificate. For this example, we will be configuring the debug certificate; however, the steps for both are exactly the same. Figure 2 shows what this process looks like.
Figure 2 The wizard for creating a push certificateClicking Configure will open up a wizard with steps that will guide you through the process. This process is very similar to creating any other provisioning profile. After completing this step, you need to download this certificate and install it in your keychain by double-clicking on it.
Setting up you provisioning profile
Now that we have created the signing certificate, we will need to create the provisioning profile to allow the application to be installed on your iPhone. Again, you don’t want to use your generic developer certificate. You must generate a new one that is specific to your app’s full bundle id.
Go to the Provisioning tab. Since we created a push certificate for debug, we must also create a debug provisioning profile. Had we created a production certificate, you would need to create an app store or adhoc certificate. Click on the New Profile button within the Development tab.
As you may have seen before, there are quite a few options that need to be set up. The first is the profile name. This can be anything you want; however, your best bet is to be very descriptive. Name it something like [Application Name] Debug. Next, you will select the certificate that the profile will be using.
If you are a single user, you should only see your certificate in the list. However, if you are on a team, you should see a certificate for every one of your team members. Just check the boxes of the teammates that will be testing the push notifications. Note that when creating a build for the app store, you will select your distribution certificate.
Following the certificate, you will need to select the app id that the profile will be used for. Finally, you must select the devices that the provisioning profile will work on. Figure 3 shows an example of what this form looks like completed.
Figure 3 Provisioning profile formAfter creating this profile, you will need to download and install it. That is about it for the certificate creation. We will now be discussing how to implement the methods in your client application to enable and receive push notifications.
The code for handling push notifications
As we mentioned earlier, the code to handle push notifications is quite simple. In fact, there are only three methods that need to be implemented. We will be walking through each of these methods and discussing their use.
The first method is the applicationDidFinishLaunching method. This method is already implemented for you in any application that you create. You simply need to add one line of code that will tell your application to register for push notifications. The following code shows you how to do this.
- (void)applicationDidFinishLaunching:(UIApplication *)app { [[UIApplication sharedApplication] registerForRemoteNotificationTypes:( UIRemoteNotificationTypeAlert |UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; }
Your application will have other setup tasks in this method; we just wanted to show you the line of code that must be added to register for push notifications. The code above will tell the device that this application wants to receive push notifications in the form of alerts, badge numbers, and sounds. You can omit any of these properties if you choose not to send them.
One thing you might be wondering is why this must be done more than once. The reason for this is the token that gets generated when setting up push notifications is not guaranteed to be the same. So, we want to touch base with Apple every time the application launches to make sure everything is correct to receive notifications.
As you may have guessed, there are some delegate methods that must be implemented to react to events generated by this registration call. The code below shows a simple implementation of these methods.
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken { [self sendProviderDeviceToken: devToken]; } - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSLog(@"Error in registration. Error: %@", err); }
The first method fires upon successful registration for push notifications. When you register to receive push notifications, your application communicates with Apple and receives back a unique device token. This token is used in all push communication with your device.
Notice we call a method sendProviderDeviceToken in our class. This is a custom method you should create to send the device token to your push provider. You may do this via a web service interaction.
The method didFailToRegisterForRemoteNotificationsWithError is for error handling. It fires when you get an error registering for push notifications. Most likely, if this method gets called, your signing certificate is invalid or the device doesn’t have an Internet connection. Make sure you put some code in this method to notify the user that there was a problem registering for notifications and they will not receive any at this point.
Now that the application has registered to receive push notifications, the next step is to handle them when they come in. Apple gives us a few methods that will allow us to control what happens when the user presses the View button on the notification alert.
The first way of handling an incoming push notification is to simply implement the code in the applicationDidFinishLaunching method. You would want to go this route if the notification was just used to open the application and did not pass any additional data. The following code shows a simple way to respond.
- (void)applicationDidFinishLaunching:(UIApplication *)application { application.applicationIconBadgeNumber = 0; [self getUpdatedDataFromServer]; }
The first and most important thing you must do here is reset the badge number to 0. If you don’t do this, the badge count will stay at whatever number was sent by the push notification. After that, you should perform any updates that are needed. In the above code, we assume that some data has changed on the server and call a method to download the updated data.
If the notification contains a custom dictionary, you must use the application:didFinishLaunchingWithOptions: method. The options variable will be an NSDictionary containing the custom values passed in.
In the event that the user is currently running the application, you must implement the application:didReceiveRemoteNotification: method. It will be called automatically and passed a dictionary containing all of the standard information including badge number, message, sound, and any custom dictionaries that were sent to the device.
After implementing the aforementioned methods, your application should now be ready to receive push notifications. One final step in preparation is to format any audio files that will be played in response to a push notification.
Preparing audio files
As noted before, when a push notification is received, it can invoke the playback of an audio file included with your application. There are many interesting scenarios for when different audio files might be appropriate. One example might be during a chess match. If a player receives a notification informing them it’s their turn, the system might simply play the default audio file. However, if they receive a notification related to a piece being captured, the system might play some sort of battle sound effects. The more creative you get with this, the more value it may add to your application.
The first thing to note when considering the audio file to play is that the file must be stored in your application’s main bundle directory. This is just the root folder that your applications files are stored in. Your audio file must be in the format of aiff, wav, or caf and limited to 30 seconds. In order to convert the audio file to one of these formats, you must use the afconvert command on you Mac. To do this, open the Terminal and navigate to the directory of the audio file you wish to convert. Next, type the afconvert command followed by -f caff -d LEI16 {INPUT} {OUTPUT}. The following shows an example of using this command to convert the file track2.mp3 to track2.caf.
/usr/bin/afconvert -f caff -d LEI16 track2.mp3 track2.caf
For corresponding display in the terminal, see figure 4.
Figure 4 Converting audio files in the terminalYou will need to do this for every sound file that you wish to invoke from a push notification.
Summary
As we have seen, push notifications offer a very simple solution to a complex problem. They give developers the ability to mimic the functionality of running their application in the background while conserving the system resources on the iPhone.
Apple has provided us with a very robust service that we are able to use free of charge. This service is the centerpiece of the entire push notification system and allows us to send simple messages from a provider to a specific iPhone with very little delay.
In order to receive the push notifications, applications must be prepared and signed with a special signing certificate generated on Apple’s website. You must create a signing certificate for use in development mode as well as debug mode when testing push notifications in your application. This certificate is used in conjunction with your private key to create the SSL certificate needed to communicate with Apple’s servers.