Additional Client-side Notification Handling

Now that you’ve pulled off the basics of push notifications, let’s look at three additions to notification handling in the client application: pushing sounds and badges, receiving notifications while running, and using notification data when not running.

Sounds and badges

When Notified registers for notifications, it specifies that it can also receive sound and badge notifications. A sound notification’s JSON payload contains the filename of a sound, and the notified application will search its application bundle for a matching file and play it if it exists. This sound file must follow the same rules as a system sound: less than 30 seconds and in a raw data format. Locate Sound12.aif that you used in Chapter 27 and add it to the Notified project in the project navigator.

In the CocoaServer project, update the method notificationDataForMessage:token: in CocoaServerAppDelegate.m to badge the application and have it play the alert sound.

 ​ ​ ​ ​/​/​ ​F​i​n​d​ ​t​h​e​ ​b​i​n​a​r​y​ ​l​e​n​g​t​h​s​ ​o​f​ ​t​h​e​ ​d​a​t​a​ ​w​e​ ​w​i​l​l​ ​s​e​n​d​
 ​ ​ ​ ​u​i​n​t​1​6​_​t​ ​t​o​k​e​n​L​e​n​g​t​h​ ​=​ ​h​t​o​n​s​(​[​t​o​k​e​n​ ​l​e​n​g​t​h​]​)​;​

 ​ ​ ​ ​/​/​ ​C​o​n​s​t​r​u​c​t​ ​t​h​e​ ​J​S​O​N​ ​p​a​y​l​o​a​d​ ​t​o​ ​d​e​l​i​v​e​r​ ​t​o​ ​t​h​e​ ​d​e​v​i​c​e​
 ​ ​ ​ ​N​S​S​t​r​i​n​g​ ​*​p​a​y​l​o​a​d​ ​=​ ​[​N​S​S​t​r​i​n​g​ ​s​t​r​i​n​g​W​i​t​h​F​o​r​m​a​t​:​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​@​"​{​​"​a​p​s​​"​:​{​​"​a​l​e​r​t​​"​:​​"​%​@​​"​,​​"​s​o​u​n​d​​"​:​​"​S​o​u​n​d​1​2​.​a​i​f​​"​,​​"​b​a​d​g​e​​"​:​1​}​}​"​,​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​e​s​c​a​p​e​d​T​e​x​t​]​;​

 ​ ​ ​ ​/​/​ ​W​e​'​l​l​ ​h​a​v​e​ ​t​o​ ​e​n​c​o​d​e​ ​t​h​i​s​ ​i​n​t​o​ ​a​ ​b​i​n​a​r​y​ ​b​u​f​f​e​r​,​ ​s​o​ ​N​S​S​t​r​i​n​g​ ​w​o​n​'​t​ ​f​l​y​
 ​ ​ ​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​p​a​y​l​o​a​d​B​u​f​f​e​r​ ​=​ ​[​p​a​y​l​o​a​d​ ​U​T​F​8​S​t​r​i​n​g​]​;​

The notification payload expanded looks like this:

{​
 ​ ​ ​ ​"​a​p​s​"​:​
 ​ ​ ​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​"​a​l​e​r​t​"​:​"​M​e​s​s​a​g​e​"​,​
 ​ ​ ​ ​ ​ ​ ​ ​"​s​o​u​n​d​"​:​"​S​o​u​n​d​1​2​.​a​i​f​"​,​
 ​ ​ ​ ​ ​ ​ ​ ​"​b​a​d​g​e​"​:​1​
 ​ ​ ​ ​}​
}​

Build and run CocoaServer and Notified. Close Notified by pressing the Home button. Deliver a notification from CocoaServer. Shortly, you will see the alert – and hear a sound and see a badge on the application icon.

After you have badged an application, you typically want to remove that badge after the user launches the application. In NotifiedAppDelegate.m, implement the following delegate method to clear the badge.

-​ ​(​v​o​i​d​)​a​p​p​l​i​c​a​t​i​o​n​D​i​d​B​e​c​o​m​e​A​c​t​i​v​e​:​(​U​I​A​p​p​l​i​c​a​t​i​o​n​ ​*​)​a​p​p​l​i​c​a​t​i​o​n​
{​
 ​ ​ ​ ​/​/​ ​W​h​e​n​ ​t​h​e​ ​u​s​e​r​ ​o​p​e​n​s​ ​t​h​e​ ​a​p​p​l​i​c​a​t​i​o​n​,​ ​c​l​e​a​r​ ​t​h​e​ ​b​a​d​g​e​ ​s​i​n​c​e​ ​w​e​'​v​e​ ​s​e​e​n​ ​t​h​e​
 ​ ​ ​ ​/​/​ ​n​o​t​i​f​i​c​a​t​i​o​n​
 ​ ​ ​ ​[​[​U​I​A​p​p​l​i​c​a​t​i​o​n​ ​s​h​a​r​e​d​A​p​p​l​i​c​a​t​i​o​n​]​ ​s​e​t​A​p​p​l​i​c​a​t​i​o​n​I​c​o​n​B​a​d​g​e​N​u​m​b​e​r​:​0​]​;​
}​

When a provider badges an application, the last notification sent determines the badge value that appears on the icon. So if a notification payload does not contain a badge value, any existing badge value is cleared.

Build and run Notified, close it, and push another notification from CocoaServer. Relaunch Notified and exit it again to see its icon. Notice that the badge has disappeared.

Accessing data in notifications

Earlier in the chapter, we mentioned that, while you can send custom data in the alert of the JSON payload of a notification, you shouldn’t send anything critical. For instance, imagine a basic chess application where you play remote opponents. It would be great to notify the user when an opponent has moved, but you wouldn’t pass the actual move in the notification. Instead, you would announce that a move has been made. When the application is launched, it will check the server for the latest move. Of course, it should do that anyway. The notification only serves as a convenient interrupt so the user doesn’t have to keep launching the application to see if that slow &*%#@ has moved yet.

Remember, delivery of push notifications is not guaranteed, so you don’t want to base your application’s logic (or your user’s experience) on them. Returning to the game example, if you did pass the opponent’s move in a push notification, and the user chose to ignore the notification, then that data would be lost.

Given that caveat, there is some data that it makes sense to pass in a notification – data the application can use to set its context after launching. If the user is launching the application from a particular notification, you could pass data that tells the application to open in the context most related to the event the notification announced.

In the chess example, say the application supports multiple games. A move, and thus a notification, would be associated with a particular game. You could pass data in the notification so that if the application is launched from the alert window, it will open directly to the game in question. Very slick. But it’s not the end of the world if the notification is not delivered or if the user ignores the notification.

Our Notified application has very little context. So to demonstrate how to access data passed in a notification, we’re just going to have the text of the alert appear in the Notified interface.

When an application that is not currently running receives a push notification, the user typically sees a pop-up window and gets a chance to launch the application. What happens if the application receiving the notification is currently running? The notification is still delivered, but the pop-up window does not appear. To get the data out of the notification, you must implement the UIApplicationDelegate method application:​didReceiveRemoteNotification: to receive it.

Open Notified’s MainWindow.xib and add a UITextView to the window. Create and connect an outlet for it, as shown in Figure 29.10.

Figure 29.10  Finished iOS XIB

Finished iOS XIB

When an iOS application is informed of a notification, it gets a dictionary that the JSON payload has been parsed into. Therefore, there will be a top-level aps dictionary that contains an alert string. In NotifiedAppDelegate.m, implement application:​didReceiveRemoteNotification: to fill out the notificationView with the alert from the notification.

-​ ​(​v​o​i​d​)​a​p​p​l​i​c​a​t​i​o​n​:​(​U​I​A​p​p​l​i​c​a​t​i​o​n​ ​*​)​a​p​p​l​i​c​a​t​i​o​n​
 ​ ​ ​ ​d​i​d​R​e​c​e​i​v​e​R​e​m​o​t​e​N​o​t​i​f​i​c​a​t​i​o​n​:​(​N​S​D​i​c​t​i​o​n​a​r​y​ ​*​)​u​s​e​r​I​n​f​o​
{​
 ​ ​ ​ ​/​/​ ​I​f​ ​w​e​ ​g​e​t​ ​a​ ​n​o​t​i​f​i​c​a​t​i​o​n​ ​w​h​i​l​e​ ​t​h​e​ ​a​p​p​ ​i​s​ ​r​u​n​n​i​n​g​,​ ​w​e​'​l​l​ ​j​u​s​t​ ​g​e​t​ ​t​h​e​ ​a​l​e​r​t​
 ​ ​ ​ ​/​/​ ​a​n​d​ ​d​i​s​p​l​a​y​ ​i​t​ ​t​o​ ​t​h​e​ ​u​s​e​r​
 ​ ​ ​ ​[​n​o​t​i​f​i​c​a​t​i​o​n​V​i​e​w​ ​s​e​t​T​e​x​t​:​[​[​u​s​e​r​I​n​f​o​ ​o​b​j​e​c​t​F​o​r​K​e​y​:​@​"​a​p​s​"​]​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​o​b​j​e​c​t​F​o​r​K​e​y​:​@​"​a​l​e​r​t​"​]​]​;​
}​

Build and run Notified and keep it running. Then push another notification from CocoaServer. After a moment, the notification message will appear in the text view.

When an application is not running, the user can launch it from the alert window. If your application wants to use the data from the notification once it is launched from the alert window, you can retrieve it from the launchOptions dictionary of application:​didFinishLaunchingWithOptions:. Add the following code to the top of this method in NotifiedAppDelegate.m.

-​ ​(​B​O​O​L​)​a​p​p​l​i​c​a​t​i​o​n​:​(​U​I​A​p​p​l​i​c​a​t​i​o​n​ ​*​)​a​p​p​l​i​c​a​t​i​o​n​
 ​ ​ ​ ​d​i​d​F​i​n​i​s​h​L​a​u​n​c​h​i​n​g​W​i​t​h​O​p​t​i​o​n​s​:​(​N​S​D​i​c​t​i​o​n​a​r​y​ ​*​)​l​a​u​n​c​h​O​p​t​i​o​n​s​
{​
 ​ ​ ​ ​/​/​ ​I​f​ ​t​h​e​ ​u​s​e​r​ ​c​h​o​o​s​e​s​ ​t​o​ ​l​a​u​n​c​h​ ​t​h​e​ ​a​p​p​l​i​c​a​t​i​o​n​ ​i​n​ ​r​e​s​p​o​n​s​e​ ​t​o​ ​a​ ​n​o​t​i​f​i​c​a​t​i​o​n​,​
 ​ ​ ​ ​/​/​ ​g​e​t​ ​t​h​e​ ​n​o​t​i​f​i​c​a​t​i​o​n​ ​i​n​f​o​r​m​a​t​i​o​n​ ​t​o​ ​u​s​e​ ​i​n​ ​t​h​e​ ​a​p​p​
 ​ ​ ​ ​N​S​D​i​c​t​i​o​n​a​r​y​ ​*​r​e​m​o​t​e​D​i​c​t​ ​=​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​[​l​a​u​n​c​h​O​p​t​i​o​n​s​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​o​b​j​e​c​t​F​o​r​K​e​y​:​U​I​A​p​p​l​i​c​a​t​i​o​n​L​a​u​n​c​h​O​p​t​i​o​n​s​R​e​m​o​t​e​N​o​t​i​f​i​c​a​t​i​o​n​K​e​y​]​;​
 ​ ​ ​ ​i​f​ ​(​r​e​m​o​t​e​D​i​c​t​)​
 ​ ​ ​ ​ ​ ​ ​ ​[​s​e​l​f​ ​a​p​p​l​i​c​a​t​i​o​n​:​a​p​p​l​i​c​a​t​i​o​n​ ​d​i​d​R​e​c​e​i​v​e​R​e​m​o​t​e​N​o​t​i​f​i​c​a​t​i​o​n​:​r​e​m​o​t​e​D​i​c​t​]​;​

Build and run Notified. Exit the application and kill it from the dock. Then send another notification and tap the View button. The text of the alert will appear in the UITextView once Notified has relaunched.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.142.2