I’ve been working with an application builder who’s looking to move an existing application that exists on a “Non Microsoft Platform” over to Windows 8.
Like a lot of applications, the data displayed comes from a set of services that are accessed over HTTP and, again, like many applications those services require authentication. Once authenticated, the data that flows is deemed to be somewhat sensitive and so is encrypted (i.e. sent over SSL).
Authentication involves swapping some credentials for some kind of access token and that access token is then flowed on subsequent services calls and it times out periodically meaning there's a need for re-authentication at that point.
In this particular case, the back-end services are all baked and there's no remit for changing them. Furthermore, the services work strictly on a "pull" model in the sense that the client pulls data from the services, the service does not attempt to "push" data down to a client via some kind of push notification mechanism.
All of that seems simple enough but it provides a bit of a challenge on Windows 8 when it comes to wanting to display live tile data like the weather application displays here in the middle of the Start Screen;
That particular screenshot shows one of the new sizes of large tiles in Windows 8.1 and if the user has given Weather so much space on their start screen then you have to assume that the weather in San Francisco is really important to them. A few quick 'fun facts' about Windows 8.1 tiles;
- They represent an entry point into the application.
- The primary tile is going to run the app.
- The app may offer the user functionality whereby they can pin additional tiles which run the app with extra parameters which might, for example, cause the app to jump to a particular section when it is run that way.
- They represent a display surface for an application.
- There are 4 sizes of tile in Windows 8.1.
- All of those tiles can display some level of information (text/images/icons) to give the user information that’s either relevant to the whole app (primary tile) or to some section of the app (secondary tile).
- They are in the user’s control.
- The user chooses whether to put a tile for an app on their Start Screen and they choose the size of the tile (subject to the tiles that the app makes available).
- The user has to explicitly consent to add second (or third, fourth, …) tiles from an app onto their Start Screen and can easily remove them afterwards.
- The user can choose whether or not they allow a tile to be “live” at particular points in time. For example, I sometimes toggle the ‘liveness’ of certain tiles if I’m doing a presentation.
In terms of how data shows up on those live tiles the process works something like this;
- Data is partitioned into what is displayed on the whole tile and what is displayed by the icon in the bottom right (the ‘badge’). Either way, information to be displayed is always defined in XML.
- Badge data fits into a simple XML schema which details the icon to be shown – this can either be one of a predefined set of glyphs (e.g. “stop/pause/play” etc.) or a number.
- Tile data fits into a slightly more complex XML schema because tiles display some combination of image/text content and the layout is pre-specified by a set of templates that define how the UI presents the content. There are a large number of templates for different combinations of text, images.
- It's possible to do some fancy tricks with live tiles including things like;
- Sending a number of concurrent updates into a tile (up to 5) and asking the system to cycle through them. This is great for giving a "liveness" effect in that the system can be cycling through information long after the app code that provided that information has exited.
- Setting expiry dates/times on updates so that the system will stop displaying them when that expiration point is reached.
There are then a number of ways that an application can ask the system to put information into a tile on the Start Screen;
- The application can be running (i.e. actually on the screen in front of the user) and some code can run to update one or more of its tiles.
- This might be in response to some action the user performed.
- This might be on a timer ticking away periodically.
- The app can package code to be run in the background by the system regardless of whether the user runs the interactive part of the app or not.
- That background code can update tiles on the user's Start Screen although it wouldn't be able to create new tiles as that requires an interactive UI.
- App runs and requests a "delivery address" for one of its tiles.
- App somehow hands that "delivery address" off to some off-device code (e.g. cloud code) that will later use it to send a tile update via push notifications.
- Off-device code authenticates with WNS service.
- Off-device code sends XML tile update payload to WNS service and specifies the "delivery address" for the XML payload.
- WNS service and Windows work together to get that new XML data to the right tile for the right app for the right user on the right device.
Of these options;
- This option does not really provide "live" tiles. Because the app code actually has to be running to make an update it's possible that the user might not run the app for weeks meaning that the tile isn't "live". Additionally, the user may run the app and then instantly switch to another app which on Windows 8 would mean that the first app is suspended and so cannot run its code to update its tile. That suspension could last indefinitely.
- This option can be made to provide a tile that can be at least as live as the frequency with which the background task runs. In Windows 8, a background task is associated with a trigger and there are a set of requirements around whether an app can use a particular type of trigger. Specifically, certain kinds of triggers are only available to apps if they have been placed on the user's lock screen. A task that keeps the live tiles up-to-date might best be associated with a timer-based trigger and Windows 8 provides 2;
- A time trigger that can be set to fire periodically down to intervals of around 15 minutes but the app has to be on the user's lock-screen.
- A maintenance trigger that can be set to fire periodically down to intervals of around 15 minutes but the device has to be on AC power.
- This option can be made to provide a tile that can be at least as live as the frequency with which the system can be configured to poll a URL on the app's behalf and that granularity is 30 minutes. The system would need to have network connectivity but that's true across all my scenarios if the data for the live tile ultimately comes from a web service.
- This option provides true push notifications – data can be sent to the device as some back-end service determines that it is timely to send it to the device.
Option (1) then isn't really viable and in my scenario Option (4) isn't viable either because this would require back-end work that the app builder can't do to implement push notifications.
Option (3) is also something that won't work because the services that are providing data need authentication and there's no way to teach the system how to authenticate when it polls the URL here.
It's worth saying that if the live-tile data is dependent on web services then, naturally, a network connection is going to be needed to get the data but it would (if necessary) be possible to have another background task which cleared tiles of any stale updates triggered whenever the network connection was lost.
This leaves the possibility of option (2). The application would need to either;
- Request a slot on the user's lock-screen such that it could then use a timer to run its background task and call web services to get the data to update its tiles with. There's a standard API for requesting that lock screen access.
- Accept that updates would only occur when on AC power and use a maintenance trigger to run its background task and call web services to get the data to update its tiles with.
Either of those is more than likely acceptable but in this particular scenario it's important to factor in the idea that the web services in question require an authenticated caller.
When the user gets the app from the Windows Store, it's easy to see a use case such as;
- User runs app for the first time.
- App realises that its background tasks have not been registered so registers them with the system perhaps on a 15-minute maintenance trigger.
- App asks the user to login.
- App makes a web service call to authenticate and get an authentication token.
- App makes web service calls passing its authentication token to get data until that token expires.
- User closes the app.
Now, 15 minutes later the maintenance trigger is going to fire and the background task(s) might run but there's a problem.
The background task can't authenticate and there's no way for it to display UI to ask the user for credentials.
At this point, it seems that the only way to proceed is for the application to keep the credentials. That is, with user consent, the application can take the service credentials and store them somewhere in its own user-partitioned, app-partitioned storage such that;
- The interactive application doesn't have to ask for credentials every time it needs them (e.g. each time the app is run or even if the app is already running and its authentication token expires).
- The background tasks of the application can get hold of credentials.
Now, in some scenarios it may not be appropriate for the application to keep credentials. For example – some apps may be subject to corporate policies which prohibit caching of credentials. That might mean that it's not possible to display live tile data if there's a reliance on authenticated service calls.
But if it's possible for an app to store credentials then this finally opens up a way in which a background task can pick up those stored credentials and use them to make authenticated web service calls.
The idea of an application wanting to store credentials is common enough for Windows to have specific functionality to support this kind of scenario whereby an app can store credentials into secure storage that is partitioned on a per-user, per-app basis and it's called the PasswordVault.
So, an interactive app can gather credentials from a user, store them into the PasswordVault and then its background tasks can (securely) pick up those credentials and make authenticated calls to back-end services.
That's a possible solution for my scenario but, it has to be said, it'd be a lot easier if the data for the tiles could be surfaced without authentication and that's perhaps an important thing to think about if you're designing services for a new app or if you have control over existing services to be re-used in a new app.