Leveraging push notifications is one of the best ways to extend the value of the application. While users don’t want to be inundated with superfluous notifications, every platform requires users to explicitly opt-in to receive notifications for a specific app. Users who choose to do so will interact and launch your application more frequently, and that helps keep your app on one of the first screens.
On both Windows Phone and Windows 8, apps that don’t leverage updated live tiles (which are often updated via notifications) tend to not make my “first page” of tiles. I want that first page of apps to be at-a-glance fresh – emails, calendar, weather, stocks, news headlines.
As a cloud guru, building these backend services in the cloud is the perfect match. Using Windows Azure, queues allow us to have durable notifications, and if our app is integrating authentication, there are services we can use to make that easy, too. The biggest cost is the VM and it’s quite low. By starting with an extra-small instance ($0.02/hour or about $15/mo.), it’s approachable by anyone and using durable storage/queues/etc., it’s redundant and scalable.
The typical approach when building notifications is to store the notification URI along with some kind of identifier on the backend service. It might be the username, it might be a phone ID, user ID, etc. Every time the application loads on the phone/tablet, you check if the URI exists and has changed. If it has changed, we update the cloud service. For example:
In this case, my settings class has a HttpNotificationUri string property that is kept in isolated storage. Assuming that’s false on the first go, we’d create the Channel:
And then we’ll need some notification event handlers:
The only event we’ll look at here is when the Phone creates the notification URI:
In SqueakBox, the raw notification is sent to the running app in order to have the app do something. If the app isn’t running or otherwise connectivity is unavailable, the notification fails. In Windows 8, there are two ways we can leverage raw notifications. Like in Squeakbox, I can register for notifications to be received only when the application is running:
But there is a far more powerful way to leverage raw notifications. Think of apps like news, magazines, weather, stocks, email, calendar, messaging – all of these, based on user consent – can register background tasks so that they can either do something on a schedule, or receive a notification to do something. A newspaper would need to simply run every morning to download the day’s paper, however other apps might send notifications to have their apps proactively do something – beyond just a tile/toast.
In this case, app must have a background agent registered and it must have lock screen privileges. This offers a lot more flexibility than raw notifications on Windows Phone. A simplistic background task would look like (from the MSDN documentation):
This task lives in its own DLL. From within the main/UI app, requesting a channel for the notification is very similar to Windows Phone:
And grabbing the payload within the app:
For the complete code sample, check out the application here on MSDN.
For Tile and Toast notifications, there is another step in authenticating with the Windows Push Notification Service (WNS). This process grants you an OAuth token for use when sending notifications. For more information on authenticating and registering the app with the developer dashboard, check out this document. Also, be sure to watch this session from //build on delivering notifications.
The other half of the equation, of course, involves sending those notifications from your service. In a follow up post, we’ll create a simple app in Windows Azure to do that, but it’s pretty easy if you’ve looked at the Windows Azure Toolkit for Windows 8, which is also mentioned in the //build talk.
Finally, I came across a post from David Burela on creating a toast notification from within an app – this is a great place to get started with understanding the basic makeup of a toast notification before trying to send one from a service.