Exploring Live Tiles for Windows 8 Store Apps

07 February 2013

Summary:
In this short post I'll be taking a look at just a few of the options available for giving your Windows Store app a Live Tile.

Introduction

If you're using Windows 8 then you already know and love live tiles. They present the user with up-to-date, relevant information in an eye-catching, fun and concise manner. Done well, live tiles can really make your app stand out from the crowd. For example, the tile for the Bing app shows the latest trending searches, along with the image-of-the-day:

The Bing tile is an excellent example of what a good live tile should be: the combination of visual appeal with relevancy. And the designers of the WinRT framework have made it almost trivially easy to create live tiles. In this post we'll take a look at a few examples of what can be achieved with a minimum of coding.

Notification Options

There are three ways in which tiles can be updated:

  1. Local: From the running app
  2. Poll: One or more URIs are polled periodically for updated tile content
  3. Push: A web server pushes updates to the tile

Local Notifications

For our first example, let's examine how to update an app's tile with some user-supplied text. Here I've created an app using the Visual Studio 2012 Windows Store Blank App template. The UI just consists of TextBox and a Button. The event handler for the Button's Tapped event does all the work:

// First, get the XML content of our app's tile
var tile = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquareText01);

// Get the list of "text" elements
var tileText = tile.GetElementsByTagName("text");

// Set the first line of text to whatever the user typed
tileText[0].InnerText = userSuppliedText;
tileText[1].InnerText = "line 2";
tileText[2].InnerText = "line 3";
tileText[3].InnerText = "line 4";

// Create a tile notification
var tileNotification = new TileNotification(tile);

// Set an expiration on the notification
tileNotification.ExpirationTime = DateTimeOffset.UtcNow.AddSeconds(60);

// Do the update notification...
TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);

The only non-obvious thing that's going on here is the retrieval of a predefined XML template that you'll use to update the app's current tile. The call to TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquareText01) specifies that we want to use the TileSquareText01 template (for a complete list of available templates, see the MSDN documentation). The XML returned looks something like this:

<tile>
    <visual>
        <binding template="TileSquareText01">
            <text id="1"></text>
            <text id="2"></text>
            <text id="3"></text>
            <text id="4"></text>
        </binding>
    </visual>
</tile>

The statement tile.GetElementsByTagName("text") returns an XmlNodeList of text elements, and we assign a string to each of the elements with tileText[n].InnerText = string.

If you run the app, enter some text and send the update notification, the app's tile will look something like the following:

In the case of our demo, we've set the notification to expire after 60 seconds, at which time the tile reverts to its default appearance, as defined in the app's package manifest. However, even if you suspend or quit the app, the update notification persists until the expiration time.

Note that if, using the code above, you send two notifications (two calls to the Update() method), the first will be "flipped" out of sight leaving the second notification to be displayed until the expiration time for the notification expires (i.e. Windows does not cycle between the two notifications).

It should be noted here that if you don't like manipulating the XML DOM, you can use the Notifications Extension library.

Poll Notifications

Poll notifications provide a great to supply truly "live" data for your app's tile. Essentially, you set up a web site or web service which serves the appropriate XML template, complete with relevant data. The app then starts a notification queue which periodically (e.g. every hour) polls the URI of the XML content for an update. You can even set up multiple URIs and have each one polled in turn.

To create a simple XML content service, use the Visual Studio 2012 ASP.NET Empty Web App template, name the project "LiveTileService" and configure it to be deployed to your local IIS (you could use IIS Express, but in that case, be sure to get the correct port number as part of the URI):

Then add two new XML files to the solution and save them as liveTileData.xml and liveTileData2.xml:

liveTileData.xml

<tile>
  <visual>
    <binding template="TileSquareText01">
      <text id="1">Update 1, line 1</text>
      <text id="2">Update 1, line 2</text>
      <text id="3">Update 1, line 3</text>
      <text id="4">Update 1, line 4</text>
    </binding>  
  </visual>
</tile>

liveTileData2.xml

<tile>
  <visual>
    <binding template="TileSquareText01">
      <text id="1">Update 2, line 1</text>
      <text id="2">Update 2, line 2</text>
      <text id="3">Update 2, line 3</text>
      <text id="4">Update 2, line 4</text>
    </binding>  
  </visual>
</tile>

Note that in the example XML above, I really ought to be returning both "square" and "wide" tile templates in the same XML package (assuming your app has a wide tile, as well as the standard square tile). However, for the purposes of this demo I just returned the square template. Production code should include both formats.

Build and deploy the solution, then open a browser and check you can access both XML files via http://localhost/LiveTileService/liveTileData.xml and http://localhost/LiveTileService/liveTileData2.xml:

Now let's add the app code that's needed to set up polling and do the notifications. Add the following to the app's App class:

sealed partial class App : Application
{
    // Make the tile updater a public property so other parts of the app can use it
    public static TileUpdater LiveTileUpdater { get; set; }

    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }

    protected override async void OnLaunched(LaunchActivatedEventArgs args)
    {
        // Setup the live-tile Uris...
        var uris = new List<Uri> 
        {
            new Uri("http://localhost/LiveTileService/liveTileData.xml"), 
            new Uri("http://localhost/LiveTileService/liveTileData2.xml")
        };

        LiveTileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
        LiveTileUpdater.Clear();  // Clear the current set of updates
        LiveTileUpdater.EnableNotificationQueue(true);  // Enable notifications
        LiveTileUpdater.StartPeriodicUpdateBatch(uris, PeriodicUpdateRecurrence.HalfHour);  // Start polling for updates
        :
        :

If you run the app, and then switch to the Start screen, you should see that your tile fairly quickly gets updated. The tile's contents then cycles between the data in the two XML files. The notifications will continue until either the tile content service created on localhost is unavailable, or we add code to the app to stop them. The important point is that the notification updates continue even if the app's suspended, running normally or not running at all:

Push Notifications

Push notifications provide a mechanism whereby updates can be pushed from your own custom "cloud service" to the app's tile. This mechanism relies on the Microsoft Windows Push Notification Service and, although it requires more setup, is in many ways preferable to polled notifications. Primarily this advance is in terms of power-efficiency: because the device doesn't have to constantly poll one or more URIs, significant power savings can be realized. Clearly this is a major advantage for mobile devices.

The main disadvantage with push notifications (at least from a quick demo perspective) is that you need to registering your app and get credentials for your cloud service through the Windows Store app development dashboard. For more details, see the MSDN documentation.

References

Conclusion

In this post we looked at just how easy it is to update the contents of your app's tile to make it eye-catching and full of relevant content. You can create "local" notifications, or use the notification queue to periodically poll a web site or web service for updates.