WinRT: Example of Using Periodic Notifications for Live Tiles
Both the Windows Phone and Windows 8 apps have live tiles which can be controlled by the developer. But where the Windows Phone tiles have the front and back sides, Windows 8 tiles have a notification queue. Live tile’s notification queue can be used to show multiple different messages to the user, like the latest news items or recent emails.
Here’s some example code which shows how to use the notification queue in a Windows 8 Metro app and how to update the queue periodically using a ASP.NET Web Api backend.
The source code for the following examples is available from GitHub.
TileUpdater
TileUpdater-class is the key to updating your tiles. It enables you to update your Metro app live tile both manually and automatically. You can get an instance of a TileUpdater using the following code:
var tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
Then using the TileUpdater instance you usually call one the following methods:
The following scenarios shows how to use the Update and StartPeriodicUpdateBatch-methods.
Notification’s ID
With notification queue enabled, the app can show up to five notifications in its tile. When a new notification is added to the queue, it replaces an older notification. But it’s possible to add an ID (to tag) a notification.
Notifications can be given a tag so that a new notification with a specific tag will replace an older notification with the same tag, regardless of its place in the queue.
Notification’s expiration time
The notifications in the notification queue may have an expiration time. This can be used in situations where the tile is used to show time sensitive information, like TV shows.
If your notification content has a significantly different useful lifespan—shorter or longer—you can explicitly set an expiration time for each notification, and it is a best practice to do so. This prevents stale or irrelevant content from remaining in the queue.
Scenario 1: Updating notification queue every time the app is run
If it’s enough that the tile’s notification queue is updated only when the app is run, there’s no need for a backend. You can update the live tile for example in MainPage’s OnNavigateTo-method.
Step 1: Enable notification queue for your live tile
If you don’t enable the notification queue, the last notification will override the previous one. So it’s only possible to show one notification on your tile.
TileUpdateManager.CreateTileUpdaterForApplication().EnableNotificationQueue(true);
Step 2: Create the tiles and notifications
After you have enabled the notification queue, you create a tile for each notification and use the TileUpdateManager to add it to the queue. In the following example code the Generator.Generate method returns the correct XML for both the wide and the small tile. The ID and the expiration time are both set:
for (var i = 0; i < 5; i++) { var tileTitle = string.Format("Local Notification {0}", i); var tilesSubtitle = DateTime.UtcNow.AddHours(i); var myTile = Generator.Generate(tileTitle, tilesSubtitle); var notification = new TileNotification(myTile.ToXmlDoc()) { ExpirationTime = tilesSubtitle.AddMinutes(15), Tag = i.ToString()}; TileUpdateManager.CreateTileUpdaterForApplication().Update(notification); }
Scenario 2: Updating notification queue periodically
In a case where the live tile should be updated automatically with new notifications, it’s necessary to create a backend. Your backend will return exactly the same XML as the local tile updates use. What’s maybe a little strange is that you’re backend won’t return all of the notification simultaneously.
For example if you want to show 5 most recent news items on your tile, your app will call your backend five times and it’s up to the backend to return a different item each time. Probably the easiest way to handle this is to give the app five different urls. Each url contains a different parameter which triggers the backend to return the correct item.
Step 1: Create the backend using ASP.NET Web Api self-hosted server
Maybe the easiest way to create a custom backend for your app is to use self-hosted ASP.NET Web Api program. Just make sure that it returns XML and not JSON.
Here’s a Web Api controller which is used to create exactly same notifications as were created in Step 1:
public class TileUpdaterController : ApiController { public HttpResponseMessage Get(int position) { var msg = string.Format("Received request for position {0}", position); Console.WriteLine(msg); var tileTitle = string.Format("Backend Noti {0}", position); var tilesSubtitle = DateTime.UtcNow.AddHours(position); var result = Generator.Generate(tileTitle, tilesSubtitle); var response = Request.CreateResponse(HttpStatusCode.OK, result); response.Headers.Add("X-WNS-Expires", tilesSubtitle.AddMinutes(15).ToString("r")); response.Headers.Add("X-WNS-Tag", position.ToString()); return response; } }
- The response header X-WNS-Expires can be used to set the expiration time for the notification
- The response header X-WNS-Tag can be used to set the id of the notification
Step 2: Start the periodic updates for your app
When the backend is ready, the TileUpdater’s StartPeriodicUpdateBatch can be used connect your app to the backend. MainPage’s OnNavigateTo is again a good place to call the TileUpdater.
var uris = new List<Uri>(); const string baseUri = "http://localhost:8080/api/tileupdater/get?position="; for (var i = 0; i < 5; i++) { uris.Add(new Uri(baseUri + i, UriKind.Absolute)); } TileUpdateManager.CreateTileUpdaterForApplication().StartPeriodicUpdateBatch(uris, PeriodicUpdateRecurrence.HalfHour);
Step 3: Enable notification queue for your live tile
As with the local updates, the app must enable the notification queue for the app.
Scenario 3: Updating notification queue every time the app is run and also periodically
Given the following scenario:
- The notification queue must be updated every time the app is run.
- The notification queue must be updated periodically by calling a backend.
In a scenario like this, it’s enough to call the StartPeriodicUpdateBatch-method when the application is run. When you call that method it will start the updates and it will (based on Fiddler) immediately call the backend and update the tiles. There’s no need to call the Update-method of TileUpdater so the same code as in Scenario 2 can be applied in here.
Notifications queue and the Windows 8 simulator
Notification queue doesn’t seem to work if the app is run inside the Windows 8 simulator. Instead the local machine deployment should be used to test the code.
Generating the live tiles using VB.NET code in a portable class library
There’s many different ways to generate the XML required for the live tile notifications. One way is to create a VB.NET portable class library and use the XML Literals. This project can then be referenced from both the backend and from the Metro app. Here’s the XML generator’s code used in these examples:
Public Shared Function Generate(title As String, time As DateTime) As XElement Dim element = <tile><visual><binding template="TileWideText09"><text id="1"><%= title %></text><text id="2"><%= time.ToString() %></text></binding><binding template="TileSquareText04"><text id="1"><%= title %></text></binding></visual></tile> Return element End Function
Source code
The source code for these examples is available from GitHub.