Questo guest post è stato scritto da Michele Locuratolo, MVP Windows Phone Development.

Con l’arrivo di Windows Phone 7, sono stati introdotti una serie di nuovi concetti relativi allo sviluppo su dispositivi mobili. Silverlight ed XNA come linguaggi di sviluppo, aprono sicuramente a nuovi scenari ed a nuove possibilità di sviluppo su quello che, di fatto, è il dispositivo elettronico più vicino ad ogniuno di noi.

Oltre a queste 2 importanti novità, ce n’è una terza che riguarda il modo di interagire e comunicare con l’utente attraverso la nostra applicazione. Parliamo di Push Notification Service. 

Un dato di fatto è che il sistema operativo non permette il multitasking per le applicazioni di terze parti. Se una applicazione passa in background, di fatto viene “congelata” per poi essere “scongelata” quando le viene ridato il focus (operazione che viene definita tombstoning). Ma come ci comportiamo quando l’applicazione ha la necessità di notificare qualcosa all’utente? Magari leggendo delle informazioni da un servizio?

E’ in questo scenario che entra in gioco il Push Notification Service.

Partiamo da questa immagine per capire meglio l’architettura.

PushNotification

(Immagine 1: architettura Push Notification Service )

Push Notification Service è, di fatto, un sistema basato su notifiche che vengono inviate al device attraverso un servizio on line.

Da questa immagine, emergono alcuni degli elementi fondamentali che contribuiscono all’architettura dell’intero sistema:

  1. direttamente sul device, compaiono 2 elementi interessanti come il push notification framework ed il push client. Il primo fornisce l’infrastruttura per gestire le notifiche mentre il secondo è il vero e proprio “proxy” per la gestione delle notifiche. 
  2. il secondo elemento è il Microsoft Push Notification Service, il cui scopo è quello di inviare la notifica al push client. Come vedremo più avanti, si tratta si server Microsoft (live).
  3. il terzo elemento della catena è rappresentato dal cloud service. Come vedremo in seguito, è questo l’elemento che genera le notifiche.

Gli attori che partecipano ad una notifica sono quindi 3, ogniuno con un ruolo specifico.

CHI avvia la richiesta di notifica, è la nostra applicazione distribuita sul device. Essa, a seguito di una conferma esplicita dell’utente (pena la bocciatura dell’applicazione sul Marketplace), dovrà aprire un push channel verso il push client del device. Questa operazione viene svolta grazie al push notification framework. Questa è, di fatto, l’operazione che predispone il device a ricevere delle specifiche notifiche. Il risultato di questa operazione di apertura del channel è, di fatto, la restituzione di un URI alla nostra applicazione. L’URI ricevuto avrà un formato simile a http://ns1.notify.live.net/… seguito da un identificativo univoco del device in uso.

Una volta ricevuto l’URI, la nostra applicazione dovrà comunicarlo ad un nostro server di back end che eroga il servizio. Ed questo rappresenta il cloud service dell’immagine di sopra. Siamo noi infatti i proprietari delle notifiche e sarà la nostra applicazione “server” a sapere quando, cosa ed a chi inviare la notifica.

Siamo dunque arrivati al punto in cui, la nostra applicazione, invia al nostro server (in the cloud) l’uri ricevuto dal push client. Il modo in cui inviamo questa notifica è a nostra cura e dobbiamo assicurarci che questa comunicazione avvenga in modo sicuro. Nel senso che possiamo possiamo decidere noi il channel con cui effettuare questa comunicazione, gestire noi l’autenticazione etc.

A questo punto, tutto si sposta sul nostro server che, al verificarsi dell’elemento da notificare, dovrà effettuare delle operazioni. Nellospecifico, il nostro server dovrà notificare al Microsoft Push Notification Service, attraverso l’URI ricevuto dal device, i dati da notificare al client. Lo farà attraverso un HTTP Post dei dati formattati con uno schema definito.

A questo punto, il Microsoft Push Notification Service invierà al push client del device la nostra notifica con le informazioni che abbiamo deciso di inviare.

L’apertura di un channel per ricevere le notifiche si esegue semplicemente creando l’istanza di un oggetto HttpNotificationChannel e richiamandone il metodo open:

HttpNotificationChannel httpChannel = new HttpNotificationChannel(channelName);
httpChannel.Open();

Una volta aperto il canale, è sufficiente sottoscriversi ad una serie di eventi utili a gestire la ricezione dell’URI nonchè gestire le notifiche in arrivo:

httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(httpChannel_ChannelUriUpdated);
httpChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(httpChannel_HttpNotificationReceived);
httpChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(httpChannel_ShellToastNotificationReceived);
httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(httpChannel_ErrorOccurred);

I tipi di notifiche

La notifica può essere di uno dei 3 tipi consentiti (Tile, Toast o Raw). Una volta ricevuta la notifica, essa verrà gestita dal device (e non dalla nostra applicazione salvo per la notifica RAW) e mostrata all’utente in base al tipo di notifica scelta.

Riassumendo i passi appena elencati:

  1. L’applicazione è in running sul device
  2. L’applicazione apre un push channel verso il push client del device
  3. Il push client rimanda un URI all’applicazione in running
  4. L’applicazione comunica l’URI ricevuto al nostro servizio di notifica (il nostro back end server)
  5. Quando si verifica l’evento da notificare, il nostro server comunica i dati al Push Service attraverso l’URI ricevuto attraverso un HTTP post all’uri dei dati formattati secondo uno schema definito
  6. Il push service invia la notifica al push client (sul device) che poi gestisce la notifica.

Vediamo ora, più nel dettaglio, quali sono I 3 tipi di notifica e come possiamo utilizzarli nelle nostre applicazioni.

L’architettura di Windows Phone 7, ci mette quindi a disposizione 3 diversi tipi di notifica, ogniuno da usare in base a specifiche (e diverse) esigenze:

  • Toast Notification
  • Raw Notification
  • Tile Notification

 

Toast Notification

La prima notifica viene denominata Toast Notification e si presenta come una barra colorata caratterizzata da una icona ed un testo (2 per la precisione), come nella figura qui sotto.

03-06-2010 22-40-52

L’icona è, di fatto, quella associata all’applicazione (la stessa che viene visualizzata nell’elenco delle applicazioni), mentre il testo viene personalizzato all’invio della notifica (e quindi può variare in base a quello che vogliamo effettivamente segnalare all’utente).

Tra i 3 tipi di notifica, la Toast è decisamente la più invasiva nonchè la più evidente. Tale notifica viene infatti mostrata in primo piano rispetto a qualsiasi applicazione e, nell’apparire, in base al profilo audio, viene emesso un segnale acustico. Data la sua peculiarità, questa notifica dovrebbe essere utilizzata solo nel caso di necessità di allertare effettivamente l’utente, altrimenti si rischia di ottenere l’effetto opposto (infastidirlo) inducendolo ad annullare la sottoscrizione.

La Toast Notification è “tappabile” (cliccabile) e, una volta cliccata, viene aperta l’applicazione che ha sottoscritto la notifica.

Altro dato importante è che la Toast Notification viene gestita dal sistema operativo (e non dalla nostra applicazione). In termini pratici, questo vuol dire che questo tipo di notifica è molto utile quando l’applicazione che l’ha sottoscritta NON è attiva. Qualora l’applicazione fosse in primo piano (e quindi utilizzata dall’utente), la notifica non verrebbe mostrata come in figura. All’interno della nostra applicazione potremmo comunque intercettare l’arrivo di questa notifica e reagire di conseguenza (magari mostrando un messaggio all’utente).

Ricapitolando:

  • La Toast Notification viene gestida dal sistema operativo e non dalla nostra applicazione
  • E’ utile per allertare l’utente quando la nostra applicazione è chiusa
  • E’ invasiva, quindi va utilizzata con accortezza
  • E’ cliccabile e, se cliccata, avvia l’applicazione

Consigli sull’utilizzo

Viste le caratteristiche di questo tipo di notifica, è evidente che il suo utilizzo deve essere valutato con attenzione.
Il discriminante con cui sceglierla è l’iportanza del messaggio che vogliamo trasmettere all’utente o meglio, l’importanza che la notifica ha per il destinatario in questione.

Qualche esempio può chiarire meglio questo concetto.
Di seguito, qualche esempio in cui avrebbe senso una Toast Notification

  • Meteo: una modifica relativa alle previsioni meteo potrebbe essere segnalato via Toast Notification, in modo da allertare l’utente della variazione
  • Sport: una modifica di un risultato sportivo, magari filtrato per oggetto di interesse (pilota, squadra, atleta etc.)
  • Tracking: ad esempio il cambio di stato una spedizione
  • Offerte speciali: ad esempio offerte dedicate e promozioni speciali

Da evitare invece tutte quelle situazioni in cui le notifiche sarebbero troppo frequenti.
Sconsiglio, ad esempio, una notifica per ogni visitatore del proprio sito web

Rispetto alla Toast Notification, la notifica di tipo RAW si differenzia per un aspetto principale: l’applicazione deve essere in esecuzione. Mentre la Toast Notification viene interamente gestita dal sistema operativo, la RAW Notification viene intercettata e, di conseguenza, gestita dall’applicazione.

Questa caratteristica la rende decisamente meno invasiva della Toast ma, come logica conseguenza, è meno probabile che venga visualizzata dall’utente.

Su un piano strettamente pratico, l’arrivo di una notifica di tipo RAW, viene gestita applicaticamente intercettando l’evento HttpNotificationReceived del channel in questo modo:

   1: void httpChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e){
   2:     //Custom Code Here
   3: }

Una volta ricevuta l’evento di notifica, è nostro compito implementare il comportamento del software in modo che “reagisca” nel modo appropriato.

Su questo punto, mi preme aprire una parentesi: Windows Phone 7 è stato ridisegnato focalizzandosi molto sull’utente che riveste un ruolo centrale nell’uso del dispositivo. Basti pensare, ad esempio, alla Toast Notification che, di fatto, non può compiere operazioni automatica (come lanciare una applicazione). E’ SEMPRE l’utente che decide cosa fare. Questa centralità dell’utente, è ovvio, deve rientrare anche nelle nostre linee guida quando progettiamo una applicazione. Ho aperto questa parentesi per evidenziare il fatto che, quando implementiamo il custom code per la gestione delle RAW Notification, è bene evitare che, ad esempio, l’applicazione apra in autonomia un form (landing page) della nostra applicazione!!

Torniamo dunque alla nostra notifica.

Un altra differenza fondamentale rispetto alla Toast Notification è che la RAW Notification può trasportare delle informazioni. Mentre nella Toast possiamo inviare solo due stringhe di testo, nella RAW possiamo inserire molte più informazioni che poi potremmo estrarre e gestire nella nostra applicazione.

L’HttpNotificationEventArgs contiene infatti il body della notifica (e.Notification.Body) che può essere “parsato” per estrarre le informazioni utili alla nostra applicazione (vedremo nel dettaglio come fare in un successivo post).

Ricapitolando:

  • La RAW Notification viene gestita dall’applicazione
  • Può trasportare dati
  • Non è invasiva come la Toast Notification

Consigli sull’utilizzo

Viste le peculiarità principali della RAW Notification, essa va utilizzata per notificare qualcosa ad un utente il cui focus è sulla nostra applicazione. Sebbene ci sia un sistema per capire se la notifica è giunta all'utente (e quindi magari mandare una Toast piuttosto che una RAW), conviene sempre distinguere le tipologie di notifiche. Ad esempio, se abbiamo distribuito una applicazione per l’acquisto di prodotti, potrebbe avere senso inviare una RAW notification quando il catalogo viene aggiornato. In questo modo, se l’utente ha l’applicazione aperta, gli verrà notificato l’aggiornamento. Diversamente, l’utente non verrà “disturbato” dalla Toast Notification ma, quando aprirà l’applicazione, il catalogo verrà automaticamente aggiornato.

Di seguito qualche esempio in cui avrebbe senso una RAW Notification:

  • Cataloghi: aggiornamento di un catalogo on line
  • Social: applicazioni di tipo social che aggiornano informazioni solo quando l’utente stà consultando l’applicazione
  • Geolocalizzazzione: applicazioni di geolocalizzazzione per cui ha senso notificare determinati eventi solo quando l’utente si trova in determinati luoghi e stà consultando l’applicazione

In conclusione, il discrimininate è sempre il focus dell’utente: se devo notificare qualcosa che ha senso solo se l’applicazione è in esecuzione.

Ultima ma non meno importante è la notifica di tipo Tile.
La caratteristica principale di questa notifica è quella di aggiornare le informazioni direttamente nella home del dispositivo. Come sappiamo infatti, tutte le applicazioni possono essere “pinnate” nella home screen del device per essere immediatamente raggiungibili dall’utente. Usando la notifica di tipo tile, abbiamo la possibilità di modificare sia l’immagine di sfondo della “mattonella”, sia il testo. Eventualmente possiamo anche aggiungere un numero (positivo) che va da 0 a 99.

Come facile immaginare, la notifica di tipo Tile funziona solo quando la nostra applicazione viene “pinnata” nella home screen.

Nell’immagine qui in basso, sono rappresentate le specifiche dell’icona. Importante è che sia quadrata e di 173x173px.

(Figura 3: specifiche della tile)

Il vantaggio di usare una tile notification è quello di poter comunicare con l’utente attraverso una rappresentazione visuale direrttamente nella home screen. Le immagini che possiamo inviare alla tile possono risiedere sia sul device che su un server remoto.

Se immaginiamo, ad esempio, una applicazione relativa alle informazioni meteo, nella tile possiamo scrivere la temperatura ed una breve descrizione e possiamo sostituire l’icona con quella che meglio rappresenta le condizioni meteo.

Altro vantaggio della tile è quello di potersi aggiornare automaticamente, senza necessità di inviare una notifica attraverso il server. Il meccanismo si chiama ShellTileSchedule.

Anatomia di una notifica

Come detto in precedenza, ogni notifica è rappresentata da un messaggio XML inviato via HTTP Post all’URI creato all’apertura del channel.

Nello specifico, una notifica di tipo Toast (ad esempio) è rappresentata dal seguente messaggio XML:

string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
   "<wp:Toast>" +
      "<wp:Text1><string></wp:Text1>" +
      "<wp:Text2><string></wp:Text2>" +
   "</wp:Toast>" +
"</wp:Notification>";

In questa pagina, la documentazione ufficiale.

Il messaggio deve essere corredato da un header custom che contiene le specifiche di invio:

X-MessageID:<UUID>
X-NotificationClass:1
X-WindowsPhone-Target:toast
X-CallbackURI: <URI>

La documentazione ufficiale relativa agli header è disponibile qui.