(X) Hide this
    • Login
    • Join
      • Generate New Image
        By clicking 'Register' you accept the terms of use .

Using periodic notification to update the tiles

(1 votes)
Andrea Boschin
>
Andrea Boschin
Joined Nov 17, 2009
Articles:   66
Comments:   9
More Articles
0 comments   /   posted on Feb 04, 2013
Categories:   Windows 8
Tweet

Push notifications are for sure an awesome tool in your hands. It gives you lot of power to make your users aware of alerts from your sources. Unfortunately, they need a server side infrastructure and also an interactive work from your side to send the notifications, and most of the times, it is like trying to kill a mosquito with a cannon. For small applications you may be discouraged from put in place all this effort for the sole purpose of supporting a few notifications.

What you are tempted to do is to create a background task that continuosly pools the network at regular timeouts to verify if there is some changes to notify to the user. This may be an option and I've shown something of similar in the article where I've talked about background tasks. Luckily, if your goal is to update your tiles and you can rely on a simple web page, which it does not need to be a real web service - there is an easy way: the use of periodic notifications.

Periodic notifications: What are they?

Up to here we met a number of notifications and all of them goes under the great family of "push notifications". "Push" means that server becomes the active part pushing to the client the notifications through the Windows Notification Service. Tile, Toast, Badge and Raw are different flavour of these notification but all them requires a lot of work on the server side, but please get in touch with Azure Mobile Services if you really need them, and spare your time. The Periodical Notification instead leave the work in the hand of the client side and it will be an automatically handled background task (completely driven by the runtime), to be in charge of exploring one (or many) url to download the notification. It is the reason becuase you do not need a real web service on the server side. You can use a simple page returning an XML, or also a static file that you can update via FTP in the worst case.

As an example let think you have an xml in your host at the following address

http://www.fakedomain.com/mynotification.xml

The file contains the xml that represents the message you should have send by push notification to the client. It may be a tile update or a badge update. Toasts notifications are excluded. Let say you would like to use a tile update:

   1: <tile>
   2:     <visual>
   3:         <binding template="TileSquarePeekImageAndText02">
   4:             <image id="1" src="http://www.fakedomain.com/mytileimage.jpg" alt="The title" /> 
   5:             <text id="1">The title</text> 
   6:             <text id="2">04/11/2010</text> /
   7:         </binding>/
   8:     </visual>
   9: </tile>

Ok, just upload it to your own hosting, or in Google Sites if you want. In the most sophisticated solution you can provide a rest web service that generates the notification on the base of whatever you want, also with something that the client pass to you in the url. I'll show something similar in the following part of the article. Then you need to enable the periodic notification into your client application. This means writing few lines of code that usually goes into the App.xaml.cs in the inizialization part.

   1: TileUpdater updater = TileUpdateManager.CreateTileUpdaterForApplication();
   2:  
   3: updater.StartPeriodicUpdateBatch(
   4:     new Uri []
   5:     {                    
   6:         new Uri("http://www.fakedomain.com/mynotification.xml")
   7:     }, 
   8:     PeriodicUpdateRecurrence.HalfHour);

If you run the application now the tile should wait a few seconds and then it will show the image and the text from the notification file. So, this happens if you have changed the url in my example xml in the box above, with a valid url of an image.

Unexpectly the update timeout is set using an enumerator. In my case it is HalfHour that means the check will be done twice in an hour but you can use the following values: HalfHour, Hour, SixHour, TwelveHour, Daily. These are predefined timeouts and you are required to choose between them instead of specifying a number of minutes. Half an hour is the same timout you can use with a background task so it does not make any difference for the purpose of your choice. You have also to be aware that the url of your notification is touched immediately when you start the periodic notification with the StartPeriodicUpdateBatch method.

Wrap up a service with a notification

If you unleash your fantasy, there are a number of beautiful usages for this type of notification. As I'm going to show you, if you have a very basic hosting where you can put an active page - it does not matter if you do it in asp.net, java, ruby, python, perl, or if you are a php addicted - you can manage to transform some source to a xml notification easily. In my case I'll show a REST web service made with WCF and webHttpBinding. First of all create and configure the service. You can do it using the Visual Studio templates and then change the default configuration manually.

   1: [ServiceContract]
   2: public interface INewsService
   3: {
   4:     [OperationContract]
   5:     [WebGet(UriTemplate="tile/{name}", BodyStyle=WebMessageBodyStyle.Bare)]
   6:     Task<XElement> Notification(string name);
   7: }

The notifcation method is set to return a Task<XElement>. This is because the method have to connect to another source via http to download the items to publish as a notification.  For the sake of completeness below there is a short configuration of the webHttpBinding. I'll not explain it in detail because it is of of the topic of this article. You have only to be aware that

The method will answer to an url made as the following: http://www.fakedomain.com/tile/12345678 it will return the xml of the notification.

   1: <system.serviceModel>
   2:   <services>
   3:     <service name="Elite.PeriodicNotifications.Web.NewsService">
   4:       <endpoint address="" 
   5:                 binding="webHttpBinding" 
   6:                 behaviorConfiguration="webHttp"
   7:                 contract="Elite.PeriodicNotifications.Web.INewsService" />
   8:     </service>
   9:   </services>
  10:   <behaviors>
  11:     <endpointBehaviors>
  12:       <behavior name="webHttp">
  13:         <webHttp defaultBodyStyle="Bare" />
  14:       </behavior>
  15:     </endpointBehaviors>
  16:     <serviceBehaviors>
  17:       <behavior name="">
  18:         <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
  19:         <serviceDebug includeExceptionDetailInFaults="false" />
  20:       </behavior>
  21:     </serviceBehaviors>
  22:   </behaviors>
  23:   <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
  24:       multipleSiteBindingsEnabled="true" />
  25: </system.serviceModel>

Then the method is implemented to download a JSON file from the Panoramio Data API and deserialize it using Json.Net. The download is made using the HttpClient class that can be awaited asynchronously.

   1: private async Task<Photo> DownloadPhoto(Uri uri)
   2: {
   3:     HttpClient client = new HttpClient();
   4:     string file = await client.GetStringAsync(uri);
   5:  
   6:     using (StringReader stringReader = new StringReader(file))
   7:     {
   8:         using (JsonReader reader = new JsonTextReader(stringReader))
   9:         {
  10:             JsonSerializer serializer = new JsonSerializer();
  11:             Response response = serializer.Deserialize<Response>(reader);
  12:             return response.Photos.RandomOrDefault();
  13:         }
  14:     }
  15: }

After the json file has been downloaded and deserialized a single photo is extracted randomly and is returned to the caller. The web service now takes the photo and compose an XElement that represents the structure of the xml required for the notification.

   1: public async Task<XElement> Notification(string name)
   2: {
   3:     Uri uri = new Uri("http://www.panoramio.com/map/get_panoramas.php?set=" + name + "&from=0&to=50&minx=-180&miny=-90&maxx=180&maxy=90&size=small&mapfilter=true");
   4:  
   5:     Photo photo = await DownloadPhoto(uri);
   6:  
   7:     return new XElement("tile",
   8:             new XElement("visual",
   9:                 new XElement("binding",
  10:                     new XAttribute("template", "TileSquarePeekImageAndText02"),
  11:                     new XElement("image",
  12:                         new XAttribute("id", 1),
  13:                         new XAttribute("src", photo.Url),
  14:                         new XAttribute("alt", photo.Title)),
  15:                     new XElement("text",
  16:                         new XAttribute("id", 1),
  17:                         photo.Title),
  18:                     new XElement("text",
  19:                         new XAttribute("id", 2),
  20:                         photo.Date.ToShortDateString())
  21:                         )));
  22: }

After this the web service is ready to be published. Calling its url results in the extraction of a random photo from panoramio. As argument you can pass an user id or the "public" and "all" keys. These return a set of images from a single user or a composite set made of the photos from all the users. Every time your tile will ask for an update it will receive a new image and as a result it will be always updated with a new photo.

Fetching notifications from multiple urls

If you have carefully read the code in my first box - the one where I've shown the setup of a periodic notification, you would have noticed that the StartPeriodicUpdateBatch method receive an array of urls as argument. This is because you can enable up to five urls to be checked simultaneously at every timeout. You have to remind that a tile can contain a queue of up to 5 notifications and then this number makes sense.

Effectively you can specify five urls and have them to update the five places in the notification queue. You have only to enable the queue using the EnableNotificationQueue method.

   1: TileUpdater updater = TileUpdateManager.CreateTileUpdaterForApplication();
   2: updater.EnableNotificationQueue(true);
   3:  
   4: updater.StartPeriodicUpdateBatch(
   5:     new Uri[]
   6:     {                    
   7:          new Uri("http://localhost:23899/NewsService.svc/tile/public")
   8:         ,new Uri("http://localhost:23899/NewsService.svc/tile/32824455")
   9:         ,new Uri("http://localhost:23899/NewsService.svc/tile/45201657")
  10:         ,new Uri("http://localhost:23899/NewsService.svc/tile/55193484")
  11:         ,new Uri("http://localhost:23899/NewsService.svc/tile/14748463")
  12:     },
  13:     PeriodicUpdateRecurrence.HalfHour);

In this example pass different arguments for each url. The first is the public feed of recent images and the other are a selection of users that have beautiful photos. This results in a roll of five images updated each 30 minutes.

A not so crazy idea

It is really clear in my mind that the periodic notification can be an easy alternative to the ones that don't want to setup (or buy) a push notification solution. I've found a number of services that offers an xslt transformation service, most of them free, and I suppose that it could be simple to build such a similar source based on these services consuming a source xml that can be transformed to the notification xml using the power of xslt. Perhaps someone would like to try Yahoo Pipes and give here a feedback :)


Subscribe

Comments

No comments

Add Comment

Login to comment:
  *      *       

From this series