Jim O'Neil
Technology Evangelist
Join App Builder
Keep The Cash! Earn $100 for every app you publish! Let me know how I can help!
In my previous blog post, I provided a high level overview of notifications in Window 8, breaking the functionality down in terms of the user experience (tiles, toast, and badges) and delivery mechanisms (local, scheduled, periodic, and push). This post will look at the common programmatic concepts of the user experience: what you can do with tiles, toast and badges, and how you accomplish that within code. Subsequent blogs posts will focus more deeply on the specific delivery mechanisms.
At its very core a notification is simply a bit of information you wish to convey to the user, and it’s the Windows 8 runtime that provides a framework for both how and when the notifications appear. Regardless of the user experience, the structure of a notification is provided via an XML template. There are predefined templates for tile, toast and badge notifications, and every notification must comply with one of these templates.
Below is an overview of the templates for each of the user interface elements (tiles, toast, and badges) along with a visual sample and the XML template that is used for that sample. The highlighted sections within the samples below indicate what you as a developer must modify to create the element. Follow the associated view schema links (in the first column) to find other options such as how to enhance a toast notification with audio and how to format the image src attribute to indicate where an image is hosted: web, local storage, or in the app package itself.
<toast> <visual> <binding template="ToastImageAndText02"> <image id="1" src="img.png" alt="image1"/> <text id="1">MarketLimit Order Reached</text> <text id="2">You just sold 200 shares of MSFT at $32.50</text> </binding> </visual> </toast>
<tile> <visual> <binding template="TileWideImageCollection"> <image id="1" src="image1.png" alt="alt text"/> <image id="2" src="image2.png" alt="alt text"/> <image id="3" src="image3.png" alt="alt text"/> <image id="4" src="image4.png" alt="alt text"/> <image id="5" src="image5.png" alt="alt text"/> </binding> </visual> </tile>
<badge value=”7” />
There’s a great deal of similarity for handling the notification content regardless of the type (tile, toast or badge), and the next few sections map out that workflow and provide pointers and links to the various notification classes that are relevant at each stage of the process. Be sure to check out the links in the green callout as well for guidance on how and when (and when not) to incorporate the various notification types in your application.
Lastly, I’ll close the post with an admittedly hodgepodge section of other important concepts and features you should be aware of as you plan out your application’s notification strategy.
Every notification type has an associated ‘manager’ class that can be used to access the available templates, each of which has a well-known name. In quasi-JavaScript the code follows the pattern:
var manager = manager_type; var xmlTemplate = manager_type.getTemplateContent(template_type);
where the italicized JavaScript class placeholders associated with each notification type are itemized in the following table (you can get to the C++, C#, and VB analogs from these links as well).
To access the template for the stock purchase toast notification shown earlier in this post, the following code would be used:
// use 'n' as namespace shortcut var n = Windows.UI.Notifications; var manager = n.ToastNotificationManager; var xmlTemplate = manager.getTemplateContent(n.ToastTemplateType.toastImageAndText02);
With the XML template (of type XmlDocument) in hand, you can use the various XML DOM methods to replace the elements (images, text, etc.) with customized data, for example:
var txt = xmlTemplate.getElementsByTagName("text"); txt[0].appendChild(xmlTemplate.createTextNode("Market Limit Order Reached")); txt[1].appendChild(xmlTemplate.createTextNode( "You just sold 200 shares of MSFT at $32.50"));
var img = xmlTemplate.getElementsByTagName("image")[0]; img.setAttribute("src", "http://jimoneil.blob.core.windows.net/tiles/stock.jpg");
That’s not hard code to write, but it’s hard to get it right! Navigating the XML DOM makes for some tedious and error prone programming, so you’ll be happy to know there’s another, more strongly-typed, way to go about this.
The Toast notifications Sample (and perhaps others) on the Windows Dev Center includes a C# project called NotificationExtensions that you can incorporate into your own projects to provide a set of strongly typed classes with the appropriate properties for each type of toast, badge, or tile notification. Instead of manipulating the DOM, you can write code like the following:
var content = ToastContent.ToastContentFactory.createToastImageAndText02(); content.textHeading.text = "Market Limit Order Reached"; content.textBodyWrap.text = "You just sold 200 shares of MSFT at $32.50";content.image.src = "http://jimoneil.blob.core.windows.net/tiles/stock.jpg";
Be aware though that the content variable above is NOT an XML type, but an abstraction of it. There is a method you'll eventually call to convert it into the XML type before sending the notification.
content
How you send the notification depends on the delivery mechanism, and while most of that discussion will be deferred to subsequent posts, I don’t want to leave you hanging! Recall that earlier I mentioned each UI notification type has an associated ‘manager’ class, and you use that class to retrieve the XML template for the notification. That manager class is also the entry point into sending the notification, regardless of the delivery mechanism. It’s a three step process:
The complete code for sending the stock purchase toast notification would then look like the following; the two lines of code that send the local notification are highlighted to complete this simple end-to-end JavaScript snippet.
// use 'n' as namespace shortcut var n = Windows.UI.Notifications; var manager = n.ToastNotificationManager; var xmlTemplate = manager.getTemplateContent(n.ToastTemplateType.toastImageAndText02); var txt = xmlTemplate.getElementsByTagName("text"); txt[0].appendChild(xmlTemplate.createTextNode("Market Limit Order Reached")); txt[1].appendChild(xmlTemplate.createTextNode( "You just sold 200 shares of MSFT at $32.50")); var img = xmlTemplate.getElementsByTagName("image")[0]; img.setAttribute("src", "http://jimoneil.blob.core.windows.net/tiles/stock.jpg");
var toast = n.ToastNotification(xmlTemplate); manager.createToastNotifier().show(toast);
In the case of toast notifications specifically, the arrival of the notification may implicitly prompt the user to click on it (such as to accept an incoming VOIP call), so you will likely want to include code in your application to respond to the interaction and open your application to a context consistent with the notification. For example, if a user clicks on the stock sale toast sample I’ve been using, he might expect the associated trading application to open right to a page with the trade confirmation details. Providing such an experience requires two main capabilities:
Continuing with the stock sale notification, I can provide launch context to the notification by adding the following to the template customization code (prior to showing the toast, of course).
var tst= xmlTemplate.getElementsByTagName("toast")[0]; tst.setAttribute("launch", '{ "confirmation" : "20120717000123" }');
When the toast comes in and the user clicks on it, the application may or may not be running, but in either case the application class will respond to a launch activation request. In response, your code can check why the application was activated – for a notification activation, you’d be looking for the argument to that callback to have a detail property of kind WebUILaunchActivatedEventArgs.
Next, you’d pull the ‘launch’ arguments from the arguments property of that same detail object, and use those values to influence the navigation – for instance, showing a stock sale transaction statement for a given confirmation id.
The code for this (below) may initially be a bit intimidating, but only because it’s part of the activation handling flow for the entire application.
e.detail.arguments
1: // in default.js
2: function activated(e) {
3: e.setPromise(WinJS.UI.processAll().then(function () {
4: if (e.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch
5: && e.detail.arguments !== "") {
6:
7: // parse out the confirmation number
8: var confNumber = JSON.parse(e.detail.arguments)["confirmations"];
9:
10: // if it's there, navigate to the specific confirmation page
11: if (typeof confNumber !== 'undefined')
12: return WinJS.Navigation.navigate(confPage.url, confNumber);
13: }
14:
15: // otherwise do the default navigation
16: var url = WinJS.Application.sessionState.lastUrl || homePage.url;
17: return WinJS.Navigation.navigate(url);
18: }));
19: }
20:
21: ...
22:
23: // wire up handler
24: WinJS.Application.addEventListener("activated", activated, false);
25: WinJS.Application.start();
The post thus far should get you well on your way to setting up notifications within your applications, but to provide that added extra touch to your users’ experience, there are a few additional items I want to bring to your attention. I won’t go into as much detail as above, since the documentation covers these topics well, but it’s important to know the various options that exist so you can incorporate them into your design as appropriate.
End users have control over whether or not your application’s tile shows as a square or wide (rectangular) one. Wide tiles are useful for more lengthy content like e-mail or social medial updates or perhaps photo and media applications. You don’t have to provide a rectangular tile option, however, if you do provide it, you cannot assume that will the size the user has displayed at any given time.
If you do opt for wide tiles, be sure that your notifications include both wide and square templates (as separate binding elements). If you neglect to send a template of the appropriate size, and the user has configured her start screen contrary to what you are sending, she will not see the notification.
Also be aware that if your application provides the user the option to display its detailed status on the Lock screen, you must also send a wide tile notification.
Above you probably noticed earlier in Table III, there are two methods to get a TileUpdater for tile notifications, one associated with the main application tile and one associated with a secondary tile. A secondary tile provides a customized experience for an application that’s already installed.
For instance, you might have a weather application installed, but want to see the weather for both your current location as well as home. If that weather application exposes the ability to create a secondary tile (typically via a “Pin to Start” option on the app bar), you could have two tiles available on the desktop associated with the same application. The secondary tile, when created, has a unique tileID and arguments that can be interpreted by the application to open to the appropriate context and allow notifications to target a specific tile.
By default, each time a new tile notification arrives, the previous notification is replaced; however, by enabling the notification queue you can have a tile cycle through up to five notifications (for instance, display stock quotes for five different ticker symbols). You can also assign tags (arbitrary labels of up to 16 characters) to each notification, and rather than pushing out the oldest notification in the queue, the runtime will replace an existing notification bearing the same tag with the new content.
You can enable the notification queue via the EnableNotificationQueue method of the TileUpdater class, and for periodic updates the startPeriodicUpdateBatch method is available to provide up to five URIs that correspond to the content to be cycled.
One thing that may surprise you is that it’s just as important (if not more important) to plan out when to stop or remove notifications, and there are certainly APIs to facilitate handling scenarios such as the following:
The XML schema for toast provides a duration attribute controlling then length of time a toast appears on screen
Long duration toasts are appropriate when the notification requires additional setup or time to respond. For instance, you’d want a VOIP request to ‘ring’ for a while on the recipient’s machine to catch her attention and give her time to connect her headset.
Windows 8, via the PC Settings option accessible from the Settings charm, allows the user to select up to seven applications for which an application icon and badge are displayed on the start screen (as shown in the yellow lasso below). Additionally, the user can select one application for which detailed text from the current tile is displayed (shown circled in red below).
To support these options, you’ll need to
There is no additional processing needed on the application developer’s part, since the Lock screen will automatically reflect the current state of the tile associated with those applications promoted there by the user.
Windows 8 runs on a wide array of devices of different size and resolutions, so ‘it works on my machine’ isn’t enough to guarantee a great experience for all of your application users. Be cognizant of image size and scale requirements, namely
Note that when a notification references invalid content, it most cases it will simply just not appear, and that’s a difficult outcome to diagnose!