<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://dotnetlombardia.org/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Il blog di Matteo Pagani</title><subtitle type="html" /><id>http://dotnetlombardia.org/b/qmatteoq/atom.aspx</id><link rel="alternate" type="text/html" href="http://dotnetlombardia.org/b/qmatteoq/default.aspx" /><link rel="self" type="application/atom+xml" href="http://dotnetlombardia.org/b/qmatteoq/atom.aspx" /><generator uri="http://telligent.com" version="5.6.582.12810">Community Server</generator><updated>2012-02-06T10:00:00Z</updated><entry><title>Il multitasking in Mango: i background transfers</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/10/12/il_2D00_multitasking_2D00_in_2D00_mango_2D00_i_2D00_background_2D00_transfers.aspx" /><id>/b/qmatteoq/archive/2012/10/12/il_2D00_multitasking_2D00_in_2D00_mango_2D00_i_2D00_background_2D00_transfers.aspx</id><published>2012-10-12T10:00:00Z</published><updated>2012-10-12T10:00:00Z</updated><content type="html">&lt;p&gt;Continuiamo il nostro percorso alla scoperta delle novità di Mango e parliamo questa volta dei &lt;strong&gt;background transfers&lt;/strong&gt;, ovvero una nuova funzionalità che ci permette di gestire i download e gli upload di dati all’interno della nostra applicazione anche quando questa non è in esecuzione.&lt;/p&gt;  &lt;p&gt;Al giorno d’oggi siamo abituati ad utilizzare due classi per gestire il flusso di dati verso l’esterno: &lt;strong&gt;WebClient&lt;/strong&gt; (più semplice da usare ma meno performante) e &lt;strong&gt;HttpWebRequest &lt;/strong&gt;(più complessa da usare ma più completa e veloce). In Mango abbiamo a disposizione una nuova classe per questo scopo, chiamata &lt;strong&gt;BackgroundTransferRequest&lt;/strong&gt;, che ha la particolarità di poter continuare a mantenere il trasferimento attivo anche ad applicazione chiusa.&lt;/p&gt;  &lt;p&gt;E’ bene ricordare che, dato che questo tipo di trasferimento può avere un impatto sulle performance e sul consumo di batteria, sono stati introdotti dei limiti analoghi a quelli per il download di applicazioni dal Marketplace: se si è collegati ad una &lt;strong&gt;rete 3G&lt;/strong&gt;, il trasferimento massimo di dati consentito&lt;strong&gt; è di 20 MB&lt;/strong&gt;, che diventano &lt;strong&gt;2 GB&lt;/strong&gt; se invece siamo collegati ad una &lt;strong&gt;rete Wi-Fi&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Prima di approfondire l’argomento, però, dobbiamo parlare di un’altra nuova feature di Mango, molto importante nell’utilizzo dei background transfers: &lt;strong&gt;il mapping dell’Isolated Storage&lt;/strong&gt;.&lt;/p&gt;  &lt;h3&gt;Un nuovo metodo di mapping dell’Isolated Storage&lt;/h3&gt;  &lt;p&gt;Nella versione attuale di Windows Phone l’unico modo per lavorare con i file memorizzati nell’Isolated Storage è utilizzare le classi messe a disposizione dal framework, come &lt;strong&gt;IsolatedStorageFile&lt;/strong&gt; e &lt;strong&gt;IsolatedStorageFIleStream&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;In Mango è stata introdotta la possibilità di esprimere i file memorizzati nell’Isolated Storage con un &lt;strong&gt;Uri, &lt;/strong&gt;in questo modo:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;private Uri destinationUrl = new Uri(&amp;quot;/shared/transfers/Cocaine.mp3&amp;quot;, UriKind.RelativeOrAbsolute);&lt;/pre&gt;

&lt;p&gt;L’esempio qui riportato è un Uri che punta al file &lt;strong&gt;Cocaine.mp3&lt;/strong&gt; memorizzato nella cartella &lt;strong&gt;transfers&lt;/strong&gt; dell’Isolated Storage. Nei background transfers questo nuovo metodo di mapping è molto importante, dato che quando viene inizializzata la classe &lt;strong&gt;BackgroundTransferRequest&lt;/strong&gt; è necessario specificare sia la sorgente che la destinazione proprio sotto forma di Uri. Questo perchè il download potrebbe terminare anche ad applicazione chiusa: in quel caso, se mantenessimo il file scaricato solamente in memoria non avremmo modo di gestirlo.&lt;/p&gt;

&lt;p&gt;In realtà, questo nuovo metodo di mapping può tornare utile in tutti gli scenari in cui l’oggetto con cui si sta lavorando esponga delle proprietà che accettano un Uri come sorgente: se prima eravamo limitati a riferirci solamente a risorse incorporate nel progetto oppure esposte sul web, da oggi possiamo anche utilizzare file memorizzati nell’Isolated Storage (pensiamo ad esempio alla proprietà &lt;strong&gt;BackgroundImage&lt;/strong&gt; delle tile).&lt;/p&gt;

&lt;h3&gt;Iniziamo il trasferimento&lt;/h3&gt;

&lt;p&gt;Ora che abbiamo capito come funziona il nuovo metodo di mapping, vediamo come gestire il trasferimento di dati. Innanzitutto dobbiamo definire un Uri sorgente (il file che vogliamo scaricare) e un Uri di destinazione (dove vogliamo salvare il file). Occhio che abbiamo l’obbligo di salvare tutti i file scaricati usando la classe &lt;strong&gt;BackgroundTransfer&lt;/strong&gt; all’interno della cartella &lt;strong&gt;shared/transfers&lt;/strong&gt; che, se non esiste, verrà creata all’occorrenza (occhio che, &lt;a href="http://qmatteoq.tostring.it/blog/post/alcuni-cambiamenti-nei-servizi-in-background-nella-beta-2-dei-tool-di-sviluppo"&gt;come raccontato in un mio post&lt;/a&gt;, la posizione di questa cartella è cambiata dalla beta1 alla beta2). Possiamo aggiungere altri file o altre sottocartelle all’interno di &lt;strong&gt;transfers&lt;/strong&gt;, possiamo spostare il file una volta terminato il download, ma non abbiamo la possibilità di scaricare direttamente i file al di fuori di essa.&lt;/p&gt;

&lt;p&gt;L’URL sorgente deve essere passato come parametro in fase di inizializzazione dell’oggetto, mentre l’URL di destinazione può essere passato sia come secondo parametro, sia definito in un secondo momento tramite la proprietà &lt;strong&gt;DownloadLocation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vediamo un esempio di codice, che poi commenteremo:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;backgroundRequest = new BackgroundTransferRequest(sourceUrl, destinationUrl);
backgroundRequest.Method = &amp;quot;GET&amp;quot;;
backgroundRequest.TransferPreferences = TransferPreferences.AllowCellularAndBattery;
backgroundRequest.TransferProgressChanged += new EventHandler&amp;lt;BackgroundTransferEventArgs&amp;gt;(backgroundRequest_TransferProgressChanged);
backgroundRequest.TransferStatusChanged += new EventHandler&amp;lt;BackgroundTransferEventArgs&amp;gt;(backgroundRequest_TransferStatusChanged);

BackgroundTransferService.Add(backgroundRequest);&lt;/pre&gt;

&lt;p&gt;Come potete notare, la classe &lt;strong&gt;BackgroundRequest&lt;/strong&gt; permette di definire le classiche impostazioni di una connessione HTTP, come il metodo (nell’esempio, POST) e gli headers. Ben più importante è sottolineare la proprietà &lt;strong&gt;TransferPreferences&lt;/strong&gt;, che permette di definire le condizioni che devono essere soddisfatte affinché il trasferimento venga mantenuto in background. Le possibili opzioni sono:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;None: &lt;/strong&gt;è l’impostazione di default, consente il trasferimento solo se il device è in ricarica e collegato ad una rete Wi-Fi. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;AllowBattery&lt;/strong&gt;: consente il trasferimento solo se il device è collegato ad una rete Wi-Fi, ma è indifferente quale tipo di alimentazione si sta usando. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;AllowCellular:&lt;/strong&gt; consente il trasferimento solo se il device è in ricarica, ma è indifferente se sia collegato ad Internet tramite una rete Wi-Fi o tramite rete cellulare. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;AllowCellularAndBattery: &lt;/strong&gt;consente sempre il trasferimento, indipendente dal tipo di alimentazione e dal tipo di rete a cui è collegato. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Infine notiamo come l’oggetto ci metta a disposizione due eventi che possiamo sottoscrivere:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;TransferProgressChanged&lt;/strong&gt;: questo evento viene scatenato ogni qualvolta la quantità di dati trasferita cambia. Tipicamente, viene utilizzato per gestire eventuali progress bar o indicatori di altro tipo che mostrino lo stato del trasferimento. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;TransferStatusChanged: &lt;/strong&gt;questo evento viene scatenato nel momento in cui lo stato del trasferimento cambia. Questo tipo di informazione ci dice non solo se il trasferimento è stato completato (&lt;strong&gt;Completed&lt;/strong&gt;), ma anche se ad esempio il device è in attesa di essere collegato ad una sorgente di alimentazione esterna (&lt;strong&gt;WaitingForExternalPower&lt;/strong&gt;), ad una rete Wi-Fi (&lt;strong&gt;WaitingForWiFi&lt;/strong&gt;) o se si trova in modalità risparmio batteria (&lt;strong&gt;WaitingDueToBatterySaverMode&lt;/strong&gt;), in base alle impostazioni che abbiamo definito in precedenza. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Per dare via al trasferimento lo dobbiamo aggiungere al &lt;strong&gt;BackgroundTransferService&lt;/strong&gt; che, analogamente a quanto fa lo &lt;strong&gt;SchedulerActionService&lt;/strong&gt; per i task, si occupa di gestire lo scheduling dei trasferimenti in background.&lt;/p&gt;

&lt;h3&gt;Nella prossima puntata&lt;/h3&gt;

&lt;p&gt;Nel prossimo post vedremo un progetto di esempio più articolato, in cui gestiremo sia gli eventi esposti dalla classe &lt;strong&gt;BackgroundTransferRequest&lt;/strong&gt;, sia il fatto che il trasferimento del file potrebbe terminare nel momento in cui la nostra applicazione è chiusa.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=742" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Mango" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Mango/default.aspx" /><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Multitasking" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Multitasking/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /><category term="Background transfer" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Background+transfer/default.aspx" /></entry><entry><title>Aprire Internet Explorer da codice in un’applicazione Metro style</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/25/aprire_2D00_internet_2D00_explorer_2D00_da_2D00_codice_2D00_in_2D00_unapplicazione_2D00_metro_2D00_style.aspx" /><id>/b/qmatteoq/archive/2012/02/25/aprire_2D00_internet_2D00_explorer_2D00_da_2D00_codice_2D00_in_2D00_unapplicazione_2D00_metro_2D00_style.aspx</id><published>2012-02-25T10:00:00Z</published><updated>2012-02-25T10:00:00Z</updated><content type="html">&lt;p&gt;Una delle applicazioni che ho sviluppato per Windows 8 è quella dedicata al mio blog, che permette di consultare i miei post più recenti sfruttando alcune delle feature di Windows 8 (sharing, notifiche, ecc.).&lt;/p&gt;  &lt;p&gt;Una delle problematiche ho dovuto affrontare nello sviluppo è stata la gestione della modalità snapped: se per quanto riguarda la pagina principale non ho avuto difficoltà (è stato sufficiente convertire una GridView orizzontale in una ListView verticale), qualche problema è sorto quando si è trattato di gestire la pagina di dettaglio, costituita da una web view con il contenuto del post. La modalità snapped, infatti, lascia troppo poco spazio affinchè la web view sia usabile. &lt;/p&gt;  &lt;p&gt;Durante il lab mi è stato dato un suggerimento molto intelligente: far si che, in modalità snapped, non venga visualizzata la pagina di dettaglio ma venga direttamente aperto Internet Explorer: in questo modo il browser va ad occupare lo spazio restante (in modalità Filled), rendendo il post leggibile.&lt;/p&gt;  &lt;p&gt;Ma come fare? Il primo passo è stato determinare lo stato in cui si trova l’applicazione: la gestione della selezione dell’elemento nella lista deve essere differente a seconda se mi trovo in modalità Snapped (apertura del browser) o in una delle qualsiasi altre disponibili (navigazione alla pagina di dettaglio).&lt;/p&gt;  &lt;p&gt;Per fare questo ci viene in aiuto la classe &lt;strong&gt;ApplicationView&lt;/strong&gt;, facente parte del namespace &lt;strong&gt;Windows.UI.ViewManagement&lt;/strong&gt;. Tale oggetto contiene la proprietà statica &lt;strong&gt;Value&lt;/strong&gt;, che è di tipo &lt;strong&gt;ApplicationViewState&lt;/strong&gt;: si tratta di un enumeratore che espone un valore per ognuno degli stati visivi disponibili (&lt;strong&gt;Snapped, Filled, FullScreenLandscape &lt;/strong&gt;e &lt;strong&gt;FullScreenPortrait&lt;/strong&gt;). Il valore di questa proprietà corrisponde allo stato visivo corrente dell’applicazione. &lt;/p&gt;  &lt;p&gt;Il secondo passo è stato trovare il modo di avviare il browser direttamente sul post selezionato, un po’ come avviene su Windows Phone quando si utilizza il launcher &lt;strong&gt;WebBrowserTask&lt;/strong&gt;. Anche in questo caso la documentazione MSDN è venuta in mio aiuto: il namespace &lt;strong&gt;Windows.System.Launcher&lt;/strong&gt; contiene una classe statica chiamata &lt;strong&gt;Launcher&lt;/strong&gt;, che espone il metodo asincrono &lt;strong&gt;LaunchUriAsync&lt;/strong&gt;, che accetta come parametro un url di tipo &lt;strong&gt;Uri&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Ecco perciò un esempio di codice in cui ci sottoscriviamo all’evento &lt;strong&gt;SelectionChanged&lt;/strong&gt; per ottenere il risultato desiderato:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (ApplicationView.Value == ApplicationViewState.Snapped)
    {
        Launcher.LaunchUriAsync(new Uri(e.AddedItems[0]));
    }
    else
    {
        Frame.Navigate(typeof (DetailPage), e.AddedItems[0]);
    }
}&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=783" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows 8" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+8/default.aspx" /></entry><entry><title>Migrazione di un’applicazione Metro style dalla Consumer Preview alla Release Preview</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/24/migrazione_2D00_di_2D00_unapplicazione_2D00_metro_2D00_style_2D00_dalla_2D00_consumer_2D00_preview_2D00_alla_2D00_release_2D00_preview.aspx" /><id>/b/qmatteoq/archive/2012/02/24/migrazione_2D00_di_2D00_unapplicazione_2D00_metro_2D00_style_2D00_dalla_2D00_consumer_2D00_preview_2D00_alla_2D00_release_2D00_preview.aspx</id><published>2012-02-24T10:00:00Z</published><updated>2012-02-24T10:00:00Z</updated><content type="html">&lt;p&gt;Come vi ho anticipato nel post precedente, le modifiche dalla Consumer Preview alla Release Preview non hanno coinvolto solo l’esperienza utente, ma anche lo sviluppo di applicazioni Metro Style.&lt;/p&gt;  &lt;p&gt;La parte che ha subito le modifiche maggiori è quella relativa a WinJS, quindi allo sviluppo di applicazioni con HTML e Javascript: non ve ne parlerò in questo post, però, perchè non ho esperienza diretta, avendo lavorato solo su applicazioni con XAML e C#.&lt;/p&gt;  &lt;p&gt;Mi sono trovato, perciò, nella situazione di dover migrare alla Release Preview la mia applicazione Ricette Toscane, il porting &lt;a href="http://www.windowsphone.com/it-IT/apps/e5032224-5400-4709-ac83-43f0cadd9cf3"&gt;dell’omonima applicazione&lt;/a&gt; per Windows Phone. Piccolo spazio promozionale: assieme ad un manipolo di altre brutte persone &lt;img class="wlEmoticon wlEmoticon-smile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Smile" src="http://dotnetlombardia.org/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-27-metablogapi/3480.wlEmoticon_2D00_smile_5F00_5E45732C.png" /&gt; l’applicazione ha superato la precertificazione, dandomi così la possibilità di avere un token di accesso per la pubblicazione. Potete vedere le altre brutte facce sul sito ufficiale &lt;a href="http://it.windows8app.eu/"&gt;http://it.windows8app.eu/&lt;/a&gt;&amp;#160;&lt;img class="wlEmoticon wlEmoticon-smile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Smile" src="http://dotnetlombardia.org/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-00-27-metablogapi/3480.wlEmoticon_2D00_smile_5F00_5E45732C.png" /&gt;&lt;/p&gt;  &lt;p&gt;Vediamo quali sono gli interventi principali che ho dovuto effettuare per adattare l’applicazione.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Il primo impatto&lt;/h3&gt;  &lt;p&gt;Il primo problema da affrontare è stato il fatto che la soluzione non compilava! Ciò è dovuto alla classe &lt;strong&gt;LayoutAwarePage&lt;/strong&gt;, dichiarata nell’omonino file all’interno della cartella &lt;strong&gt;Common, &lt;/strong&gt;che&lt;strong&gt;&amp;#160;&lt;/strong&gt;ha subito delle modifiche: da tale classe ereditano le pagine dell’applicazione basate sul template standard e contiene una serie di facilitazioni che semplificano la gestione dei vari stati visuali di una pagina (landscape, portrait, snapped, ecc.).&lt;/p&gt;  &lt;p&gt;Per riuscire a compilare il progetto ho perciò creato un nuovo progetto “vuoto” utilizzando la nuova RC di Visual Studio 2012 e ho copiato la cartella &lt;strong&gt;Common&lt;/strong&gt;, sovrascrivendo quella del vecchio progetto.&lt;/p&gt;  &lt;p&gt;L’intervento non è stato perciò sufficiente: l’applicazione compilava ma, appena superata la splash screen, si verificava un’eccezione nel parsing dello XAML, nello specifico &lt;strong&gt;error HRESULT E_FAIL has been returned from a call to a COM. &lt;/strong&gt;A poco è servito cercare di isolare il problema: il messaggio di errore è assolutamente criptico e non da alcuna indicazione sulla causa del problema.&lt;/p&gt;  &lt;p&gt;La soluzione più semplice è stata perciò creare un nuovo progetto e, man mano, riportare i file del vecchio progetto nel nuovo progetto, prestando attenziones a non sovrascrivere i nuovi file generati da Visual Studio che sono cambiati con la Release Preview (ad esempio, quelli contenuti nella cartella &lt;strong&gt;Common&lt;/strong&gt; o il file &lt;strong&gt;App.xaml&lt;/strong&gt;).&lt;/p&gt;  &lt;p&gt;Con questo intervento il problema è stato risolto: l’applicazione compila e la pagina principale viene visualizzata correttamente.&lt;/p&gt;  &lt;h3&gt;Il SuspensionManager&lt;/h3&gt;  &lt;p&gt;Tra le novità nelle applicazioni Metro Style c’è il &lt;strong&gt;SuspensionManager&lt;/strong&gt;, una classe che semplifica la gestione del ciclo di vita nelle applicazioni che fanno uso di pagine basate sulla classe &lt;strong&gt;LayoutAwarePage: &lt;/strong&gt;il &lt;strong&gt;SuspensionManager&lt;/strong&gt; viene infatti utilizzato in automatico nell’&lt;strong&gt;App.xaml.cs&lt;/strong&gt; (nell’evento &lt;strong&gt;OnLaunched&lt;/strong&gt;, scatenato quando l’applicazione viene avviata) e negli eventi di navigazione (&lt;strong&gt;OnNavigatedTo &lt;/strong&gt;e &lt;strong&gt;OnNavigatedFrom&lt;/strong&gt;) per salvare e recuperare lo stato dell’applicazione, nel caso in cui questa venga terminata (vi ricordo, infatti, che le applicazioni Windows 8 hanno un ciclo di vita pressochè identico a quello delle applicazioni Windows Phone e, quando si trovano in sospensione, possono essere terminate prematuramente in caso di esaurimento delle risorse disponibili).&lt;/p&gt;  &lt;p&gt;Di default le pagine create dal template standard di Windows 8 implementano un override dell’evento &lt;strong&gt;NavigatedTo&lt;/strong&gt;, che viene utilizzato solitamente per caricare i dati da mostrare nella pagina corrente: ad esempio, in una tipica situazione master – detail l’elemento selezionato viene passato proprio tramite le API per la navigazione di Windows 8 e, per tale motivo, l’informazione viene recuperata nell’evento &lt;strong&gt;OnNavigatedTo. &lt;/strong&gt;Il problema, però, è che la classe &lt;strong&gt;LayoutAwarePage&lt;/strong&gt; contiene un’implementazione dei metodi di navigazione che salva e recupera lo stato in automatico tramite il &lt;strong&gt;SuspensionManager&lt;/strong&gt;: il risultato è che, se voi non chiamate il metodo base prima di eseguire le operazioni specifiche, otterrete un errore in fase di navigazione verso un’altra pagina, perchè il &lt;strong&gt;SuspensionManager&lt;/strong&gt; non troverà i dati che ha salvato.&lt;/p&gt;  &lt;p&gt;Occorre ricordarsi perciò di includere sempre la chiamata al metodo base come nell’esempio:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
   //carico i dati della pagina
}&lt;/pre&gt;

&lt;p&gt;Nel mio caso, ottenevo un’eccezione dato che la versione sviluppata per la Consumer Preview non aveva questo requisito, perciò la chiamata al metodo base era assente.&lt;/p&gt;

&lt;h3&gt;Nuovo prefisso per gli URL che puntano ai file di progetto&lt;/h3&gt;

&lt;p&gt;Il terzo e ultimo problema l’ho riscontrato nella gestione delle tile secondarie. Creare una tile secondaria in un’applicazione Windows 8 è molto semplice, come potete vedere nell’esempio:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;SecondaryTile secondaryTile = new SecondaryTile(id, shortName, displayName, arguments, options,
                                                new Uri(logo));

await secondaryTile.RequestCreateAsync();&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Si crea una nuova istanza della classe &lt;strong&gt;SecondaryTile &lt;/strong&gt;(passando alcuni parametri che definiscono le caratteristiche della tile, come l’id identificativo e il testo visualizzato) e si richiama il metodo &lt;strong&gt;RequestCreateAsync&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nella versione Consumer Preview si utilizzava il prefisso &lt;strong&gt;ms-resource &lt;/strong&gt;per creare un oggetto di tipo &lt;strong&gt;Uri&lt;/strong&gt; che puntasse ad un file del progetto: nell’esempio, la variabile &lt;strong&gt;logo&lt;/strong&gt; puntava ad un’immagine all’interno della cartella &lt;strong&gt;Assets&lt;/strong&gt; ed era perciò del tipo:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ms-resource:Assets/logo.png&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nella Release Preview, però, nel momento in cui andavo a creare una tile si scatenava un’eccezione, che mi comunicava che uno dei parametri passati in fase di creazione della tile non era valido. Una breve indagine e, grazie alla documentazione MSDN, ho scoperto che nella Release Preview il prefisso &lt;strong&gt;ms-resource &lt;/strong&gt;è stato rimpiazzato da &lt;strong&gt;ms-appx:///.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Il percorso all’immagine utilizzata per la tile è diventata perciò:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ms-appx:///Assets/logo.png&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;Un ultimo consiglio&lt;/h3&gt;

&lt;p&gt;Un ultimo consiglio quando sviluppate un’applicazione Windows 8 è quello di separare gli stili standard da quelli creati ad hoc da voi: se dovete creare degli stili non includeteli perciò nel file &lt;strong&gt;StandardStyles.xaml, &lt;/strong&gt;ma inseriteli in un file di tipo &lt;strong&gt;ResourceDictionary&lt;/strong&gt; a parte e dichiaratelo nell’&lt;strong&gt;App.xaml.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In questo modo se, dalla Release Preview alla RTM, dovessero cambiare nuovamente alcuni stili standard, sarà sufficiente sovrascrivere il vecchio file con il nuovo, senza che corriate il rischio di perdere i vostri stili.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=782" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows 8" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+8/default.aspx" /></entry><entry><title>Come testare il Search contract di Windows 8</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/23/come_2D00_testare_2D00_il_2D00_search_2D00_contract_2D00_di_2D00_windows_2D00_8.aspx" /><id>/b/qmatteoq/archive/2012/02/23/come_2D00_testare_2D00_il_2D00_search_2D00_contract_2D00_di_2D00_windows_2D00_8.aspx</id><published>2012-02-23T10:00:00Z</published><updated>2012-02-23T10:00:00Z</updated><content type="html">&lt;p&gt;Una delle caratteristiche più interessanti per le applicazioni di terze parti di Windows 8 è quella dei contract: si tratta, letteralmente, di contratti tra l’applicazione e il sistema operativo, che permetteno di integrarla con gli strumenti offerti da Windows 8.&lt;/p&gt;  &lt;p&gt;Uno dei contract più utilizzati è il Search contract, che permette di includere la nostra applicazione tra i possibili risultati di una ricerca lanciata tramite il sistema operativo (tramite il pulsante &lt;strong&gt;Search&lt;/strong&gt; presente nella barra laterale o semplicemente iniziando a digitare un testo all’interno del nuovo menu &lt;strong&gt;Start&lt;/strong&gt;).&lt;/p&gt;  &lt;p&gt;Implementare il Search contract è piuttosto semplice: si tratta di una delle voci disponibili nel menu &lt;strong&gt;Add New Item&lt;/strong&gt; di Visual Studio 11. In automatico, sarà aggiunta:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;La dichiarazione all’interno del file di manifest. &lt;/li&gt;    &lt;li&gt;Una nuova pagina all’interno dell’applicazione, che mostrerà i risultati della ricerca. &lt;/li&gt;    &lt;li&gt;L’aggiunta, all’interno del file &lt;strong&gt;App.xaml.cs, &lt;/strong&gt;dell’evento &lt;strong&gt;OnSearchActivated&lt;/strong&gt;, che è il punto di ingresso dell’applicazione nel caso in cui venga attivata da una ricerca. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Quest’ultimo evento restituisce un parametro di tipo &lt;strong&gt;SearchActivatedEventArgs&lt;/strong&gt;, che contiene la proprietà &lt;strong&gt;QueryText&lt;/strong&gt; con il testo cercato dall’utente. Dopodichè il controllo viene passato alla pagina di ricerca e sta a noi includere la logica necessaria per recuperare i risultati, a seconda della sorgente dati che sta alla base della nostra applicazione.&lt;/p&gt;  &lt;p&gt;Durante la fase di testing potrebbe sorgere però il dubbio su come fare debug di uno scenario che, all’apparenza, non sembra testabile: l’attivazione dell’applicazione in seguito ad una ricerca. Fintanto che la ricerca viene lanciata mentre è in esecuzione non ci sono problemi: è sufficiente avviare il debugger e, una volta che l’applicazione è aperta, effettuare la ricerca.&lt;/p&gt;  &lt;p&gt;L’utente però potrebbe anche lanciare la ricerca senza aver avviato in precedenza l’applicazione: in questo caso abbiamo la necessità di testare lo scenario in cui l’applicazione, in partenza, è chiusa, perciò il debugger non è attivo. Ad aggirare questo inconveniente ci viene in aiuto Visual Studio 11, grazie ad un’opzione che mi ha fatto scoprire il buon &lt;a href="http://blogs.ugidotnet.org/corrado"&gt;Corrado&lt;/a&gt;: se facciamo tasto destro sul progetto, scegliamo &lt;strong&gt;Properties&lt;/strong&gt;, dopodichè ci spostiamo nella sezione &lt;strong&gt;Debug &lt;/strong&gt;troveremo la voce &lt;strong&gt;Do not launch, but debug my code when it starts&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_2_12.png"&gt;&lt;img title="image" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="image" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_thumb_13.png" width="474" height="245" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Quando questa opzione è attiva, premendo F5 sarà avviato solamente il debugger: nel momento in cui l’applicazione verrà eseguita (sia in maniera tradizionale tramite un tap sulla tile, sia in seguito ad una ricerca, sia in seguito all’utilizzo di uno share contract per la condivisione, ecc.) il debugger si collegherà, dandoci accesso a tutto quello a cui siamo abituati (breakpoint, watch, ecc.). A questo punto vi basta perciò, senza aprire l’applicazione, lanciare la ricerca per testare il vostro scenario.&lt;/p&gt;  &lt;p&gt;Questo meccanismo funziona per qualsiasi test che richieda che, di base, l’applicazione non sia in esecuzione: un altro esempio potrebbe essere l’avvio dell’applicazione da una tile secondaria.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=781" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows 8" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+8/default.aspx" /><category term="WinRT" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/WinRT/default.aspx" /></entry><entry><title>Windows Phone Commands: una preziosa estensione per Visual Studio</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/21/windows_2D00_phone_2D00_commands_2D00_una_2D00_preziosa_2D00_estensione_2D00_per_2D00_visual_2D00_studio.aspx" /><id>/b/qmatteoq/archive/2012/02/21/windows_2D00_phone_2D00_commands_2D00_una_2D00_preziosa_2D00_estensione_2D00_per_2D00_visual_2D00_studio.aspx</id><published>2012-02-21T10:00:00Z</published><updated>2012-02-21T10:00:00Z</updated><content type="html">&lt;p&gt;Se siete sviluppatori Windows Phone (cosa molto probabile se state leggendo questo blog &lt;img class="wlEmoticon wlEmoticon-smile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Smile" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/wlEmoticon-smile_2_76.png" /&gt; ) vi farà sicuramente piacere fare la conoscenza di &lt;strong&gt;Windows Phone Commands&lt;/strong&gt;, una preziosa estensione di Visual Studio che va a migliorarne le funzionalità per quanto riguarda il testing delle applicazioni.&lt;/p&gt;  &lt;p&gt;L’estensione è installabile dalla Visual Studio Gallery all’indirizzo &lt;a title="http://visualstudiogallery.msdn.microsoft.com/945a718f-82d5-429f-a0b1-88bd6202c1a3" href="http://visualstudiogallery.msdn.microsoft.com/945a718f-82d5-429f-a0b1-88bd6202c1a3"&gt;http://visualstudiogallery.msdn.microsoft.com/945a718f-82d5-429f-a0b1-88bd6202c1a3&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Una volta installata, si può accedere al tool dal menu &lt;strong&gt;View – Other windows&lt;/strong&gt; di Visual Studio:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/AppMenu_2.png"&gt;&lt;img title="AppMenu" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="AppMenu" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/AppMenu_thumb.png" width="431" height="357" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Il tool permette, dalla schermata principale, di collegarsi sia all’emulatore che ad un device reale. Dopodichè avremo accesso a diverse funzioni: &lt;/p&gt;  &lt;h3&gt;Informazioni sul device&lt;/h3&gt;  &lt;p&gt;Una volta connesso al dispositivo, il tool è in grado di mostrare alcune preziose informazioni come la build del sistema operativo, il tipo di processo e la quantità di memoria disponibile. Per collegarsi, è sufficiente premere l’icona del fulmine, selezionare dal menu a tendina il tipo di dispositivo e premere &lt;strong&gt;Connect&lt;/strong&gt;.&lt;/p&gt;  &lt;h3&gt;Accedere a applicazioni ed impostazioni “nascoste” dell’emulatore&lt;/h3&gt;  &lt;p&gt;Come sappiamo, l’emulatore contiene una versione minimale del sistema operativo, che nasconde molte delle applicazioni e delle impostazioni che sono disponibili invece su un device reale. Questo a volte limita la possibilità di testare alcuni tipi di applicazioni (ad esempio, quelle in grado di integrarsi nell’hub Pictures) o determinate condizioni (ad esempio, i servizi di geolocalizzazione disabilitati). Tramite la sezione accessibile con la terza icona (quella con il simbolo di una cartella e di un piccolo ingranaggio) è possibile visualizzare l’elenco delle applicazioni native e delle voci della sezione Settings del sistema operativo, che possono poi essere aperte con un click.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTMLad019df.png"&gt;&lt;img title="SNAGHTMLad019df" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTMLad019df" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTMLad019df_thumb.png" width="342" height="342" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Esplorare l’Isolated Storage&lt;/h3&gt;  &lt;p&gt;L’SDK di Windows Phone 7.5 ha introdotto un tool per esplorare l’isolated storage di un’applicazione: purtroppo però si tratta di un tool a linea di comando, poco intuitivo e user friendly. Il tool integrato all’interno dei Windows Phone Commands offre un’interfaccia visuale molto semplice, che permette di vedere i file e le cartelle all’interno dell’isolated storage; di scaricare un file sul computer per analizzarlo; di caricare un file dal nostro computer. Per accedere a questo tool è sufficiente premere sempre la terza icona dell’estensione: in cima alla sezione troverete tutte le applicazioni di terze parti installate sul telefono, identificate da un guid. Per ognuna di queste avrete una serie di opzioni (ad esempio, per lanciare o disinstallare l’applicazione): il terzo pulsante è quello che consente di accedere all’Isolated Storage Explorer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/sc_Explo1.png"&gt;&lt;img title="sc_Explo1" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="sc_Explo1" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/sc_Explo1_thumb.png" width="257" height="358" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Deploy e update di applicazioni&lt;/h3&gt;  &lt;p&gt;E’ possibile fare il deploy di applicazioni non solo dal tool &lt;strong&gt;Application Deployment &lt;/strong&gt;o da Visual Studio, ma anche tramite questa estensione: il vantaggio è che potete anche installare uno XAP simulando un update, dandovi così la possibilità di testare anche scenari di aggiornamento della vostra applicazione (ad esempio, per verificare l’integrità dei dati o l’aggiornamento dello schema del database). Potete accedera a questaa opzione con la quarta icona, con il simbolo di un telefono e di un martello.&lt;/p&gt;  &lt;p&gt;&lt;img alt="sm1" src="http://download.codeplex.com/Download?ProjectName=wphonecommands&amp;amp;DownloadId=353651" /&gt;&lt;/p&gt;  &lt;h3&gt;Editor visuale del file di manifest&lt;/h3&gt;  &lt;p&gt;Se siete sviluppatori Windows Phone dovreste conoscere molto bene il file di manifest: tale file, contenuto nella cartella &lt;strong&gt;Properties &lt;/strong&gt;di ogni progetto, è un file XML contenente tutte le informazioni che identificano l’applicazione: titolo, numero di versione, feature del telefono utilizzate, ecc. Purtroppo Visual Studio non include un editor visuale che permette di modificare le varie voci: è necessario modificare manualmente il file. L’ultimo tool incluso in questa estensione cerca di sopperire a questo limite, offrendo un’interfaccia visuale per agire sul file di manifest. Potete accedere tramite l’ultima icona, con il simbolo di un foglio e di una pergamena.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTMLae0f06f.png"&gt;&lt;img title="SNAGHTMLae0f06f" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTMLae0f06f" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTMLae0f06f_thumb.png" width="222" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=779" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /><category term="Visual Studio" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Visual+Studio/default.aspx" /><category term="Windows Phone Commands" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone+Commands/default.aspx" /></entry><entry><title>Due importanti novità per il Marketplace di Windows Phone</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/21/due_2D00_importanti_2D00_novita_2D00_per_2D00_il_2D00_marketplace_2D00_di_2D00_windows_2D00_phone.aspx" /><id>/b/qmatteoq/archive/2012/02/21/due_2D00_importanti_2D00_novita_2D00_per_2D00_il_2D00_marketplace_2D00_di_2D00_windows_2D00_phone.aspx</id><published>2012-02-21T10:00:00Z</published><updated>2012-02-21T10:00:00Z</updated><content type="html">&lt;p&gt;E’ fresca &lt;a href="http://windowsteamblog.com/windows_phone/b/windowsphone/archive/2012/04/24/two-marketplace-changes-and-how-they-affect-you.aspx"&gt;la notizia da parte del team&lt;/a&gt; di Windows Phone di due importanti cambiamenti che coinvolgono il Marketplace e che, soprattutto il secondo, hanno un impatto non indifferente (in senso positivo, a mio avviso) per gli sviluppatori. Ma vediamoli in dettaglio.&lt;/p&gt;  &lt;h3&gt;No more Zune&lt;/h3&gt;  &lt;p&gt;Attualmente ci sono tre modi per scaricare un’applicazione Windows Phone: dal telefono, dal marketplace web o da Zune. A partire dai prossimi giorni rimarrano attive solamente le prime due possibilità: &lt;strong&gt;non sarà più consentito acquistare o scaricare applicazioni dal Marketplace tramite Zune&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Personalmente, non mi sembra un grande danno: non è un segreto che la parte di gestione delle applicazioni di Zune sia piuttosto limitata e le statistiche in possesso di Microsoft hanno confermato che la maggior parte degli utenti utilizza il telefono e il marketplace web per cercare e installare le proprie applicazioni. Fino a che non verrà introdotta una gestione delle applicazioni più efficiente, non credo che qualcuno ne sentirà la mancanza &lt;img class="wlEmoticon wlEmoticon-smile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Smile" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/wlEmoticon-smile_2_77.png" /&gt;&lt;/p&gt;  &lt;h3&gt;No Windows Phone 7.5, no party!&lt;/h3&gt;  &lt;p&gt;Windows Phone 7.5 è ormai una realtà da diversi mesi e non esiste device di prima generazione sul mercato che non abbia ricevuto l’aggiornamento. Per tale motivo e in previsione degli investimenti futuri di Microsoft sul marketplace in termini di funzionalità e sicurezza a partire dai prossimi giorni il download e l’acquisto di applicazioni dal Marketplace&lt;strong&gt; non sarà più disponibile per gli utenti che stanno ancora utilizzando la versione 7.0 di Windows Phone&lt;/strong&gt;. Sarà possibile solamente sfogliare il Marketplace ma, in caso di download, comparirà un messaggio di errore. In questo modo, anche gli sviluppatori saranno sollevati dal compito di mantenere aggiornate due versioni distinte dell’applicazione, una per Windows Phone 7.0 e una per Windows Phone 7.5 e successivi (vi ricordo, infatti, che con il rilascio della versione 7.5 Microsoft aveva dato la possibilità agli sviluppatori di caricare e mantenere due XAP separati per entrambe le versioni del sistema operativo).&lt;/p&gt;  &lt;p&gt;Anche questa, personalmente, mi sembra una buona notizia: spingere gli utenti ad avere un dispositivo il più aggiornato possibile è sicuramente una buona strategia, che avvantaggia tanto gli sviluppatori (che possono creare applicazioni senza preoccuparsi della retrocompatibilità) sia gli utenti (che possono beneficiare delle tante novità introdotte in Windows Phone 7.5).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=780" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /><category term="Marketplace" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Marketplace/default.aspx" /><category term="Zune" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Zune/default.aspx" /></entry><entry><title>Effettuare il parsing di un file XML in un’applicazione Metro style per Windows 8</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/20/effettuare_2D00_il_2D00_parsing_2D00_di_2D00_un_2D00_file_2D00_xml_2D00_in_2D00_unapplicazione_2D00_metro_2D00_style_2D00_per_2D00_windows_2D00_8.aspx" /><id>/b/qmatteoq/archive/2012/02/20/effettuare_2D00_il_2D00_parsing_2D00_di_2D00_un_2D00_file_2D00_xml_2D00_in_2D00_unapplicazione_2D00_metro_2D00_style_2D00_per_2D00_windows_2D00_8.aspx</id><published>2012-02-20T10:00:00Z</published><updated>2012-02-20T10:00:00Z</updated><content type="html">&lt;p&gt;Mi sto cimentando nel compito di portare una delle applicazioni sviluppate da me e Marco Leoncini (la serie dedicata alle ricette italiane) da Windows Phone a Windows 8: una delle prime sfide che mi sono trovato ad affrontare è il porting dei dati. L’applicazione Windows Phone si appoggia infatti ad un database SQL CE, che al momento non è compatibile con Windows 8. La soluzione più semplice da noi scelta è l’utilizzo di un file XML: alla fine la struttura del database era molto semplice ed era costituita da un’unica tabella con l’elenco delle ricette.&lt;/p&gt;  &lt;p&gt;Nel mio caso, non ho la necessità di memorizzare dati nello storage: il file XML contenente l’elenco delle ricette è incluso nel progetto di Visual Studio, dato che deve essere di sola lettura, in quanto nella mia applicazione l’utente può solo consultare le ricette e e non modificarle.&lt;/p&gt;  &lt;p&gt;Il primo problema era perciò capire come leggere il file presente all’interno del progetto: in Windows Phone avrei utilizzato ad esempio il metodo &lt;strong&gt;GetResourceStream&lt;/strong&gt; esposto dalla classe &lt;strong&gt;Application&lt;/strong&gt;, che permette di accedere proprio ai file inclusi all’interno del progetto. Dopodichè avrei sfruttato la classe &lt;strong&gt;XDocument &lt;/strong&gt;per effettuare il parsing dell’XML e avrei utilizzato LINQ to XML per manipolare i dati. Ecco un esempio:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;Uri uri = new Uri(&amp;quot;recipe.xml&amp;quot;, UriKind.Relative);
StreamResourceInfo sri = Application.GetResourceStream(uri);
XDocument doc = XDocument.Load(sri.Stream);

// eseguo le query per recuperare i dati sul file XML&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Il problema è che la classe &lt;strong&gt;Application&lt;/strong&gt; non è disponibile in Windows 8 e quindi non si è in grado di utilizzare il metodo &lt;strong&gt;GetResourceStream. &lt;/strong&gt;Spulciando nella documentazione di Windows 8 ho scoperto che tramite WinRT possiamo accedere a diversi tipi di storage: c’è quello locale dell’applicazione, ci sono le librerie di sistema (come la cartella Documents o Pictures) e così via. Uno di questi storage consente proprio di accedere alla “cartella” dell’applicazione, cartella che viene nascosta dal pacchetto preparato da Visual Studio nel formato .appx (che è l’equivalente dello XAP delle applicazioni Windows Phone, ovvero un pacchetto che contiene tutto il necessario per far funzionare l’applicazione, come librerie, contenuti, manifest, ecc.).&lt;/p&gt;

&lt;p&gt;Una volta fatto il build della nostra applicazione Metro sytle andiamo nella cartella &lt;strong&gt;bin/Debug &lt;/strong&gt;all’interno del nostro progetto: troveremo una cartella &lt;strong&gt;AppX, &lt;/strong&gt;che rappresenta il contenuto del nostro pacchetto.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML73789ec.png"&gt;&lt;img title="SNAGHTML73789ec" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTML73789ec" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML73789ec_thumb.png" width="561" height="400" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La prima cosa da fare è perciò quella di selezionare il file XML incluso nel nostro progetto e, dalla finestra Proprietà, impostare la &lt;strong&gt;Build Action &lt;/strong&gt;su &lt;strong&gt;Content&lt;/strong&gt; e &lt;strong&gt;Copy to Output Directory&lt;/strong&gt; su &lt;strong&gt;Copy if newer&lt;/strong&gt;. In questo modo il file XML verrà incluso all’interno del pacchetto.&lt;/p&gt;

&lt;p&gt;A questo punto da codice possiamo accedervi grazie allo storage chiamato &lt;strong&gt;InstalledLocation, &lt;/strong&gt;che espone il metodo &lt;strong&gt;GetFileAsync()&lt;/strong&gt; che permette di recuperare un file dal pacchetto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Importante!&lt;/strong&gt; Eravamo già abituati con Windows Phone, ma in Windows 8 questo concetto è ancora più importante: tutte le operazioni che possono impiegare più di 50 millisecondi per essere completate sono asincrone in WinRT! La differenza, che ci semplifica un po’ l’utilizzo di questo metodo di programmazione, è che WinRT supporta nativamente le parole chiave &lt;strong&gt;async &lt;/strong&gt;e &lt;strong&gt;await, &lt;/strong&gt;introdotte in C# 5, che permettono di scrivere codice che all’apparenza sembra sincrono ma in realtà viene eseguito su thread differenti.&lt;/p&gt;

&lt;p&gt;Il trucco in questo caso sta nel:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;marcare la funzione che stiamo creando con la parola chiave &lt;strong&gt;async&lt;/strong&gt; &lt;/li&gt;

  &lt;li&gt;anteporre alla chiamata al metodo asincrono la parola chiave &lt;strong&gt;await&lt;/strong&gt;. In questo modo il codice che scriveremo sembrerà asincrono (una riga sotto l’altra), ma in realtà, grazie alla parola chiave await, le righe successive non verranno eseguite fino a che l’operazione asincrona non ha restituito un risultato. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Occhio all’inghippo&lt;/h3&gt;

&lt;p&gt;Prima di spiegarvi l’inghippo di cui sto parlando, eccovi l’XML di esempio che ho usato per questi test:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;
&amp;lt;recipes&amp;gt;
  &amp;lt;recipe&amp;gt;
    &amp;lt;title&amp;gt;Pasta al pomodoro&amp;lt;/title&amp;gt;
    &amp;lt;ingredients&amp;gt;Pasta, pomodoro, formaggio&amp;lt;/ingredients&amp;gt;
  &amp;lt;/recipe&amp;gt;
  &amp;lt;recipe&amp;gt;
    &amp;lt;title&amp;gt;Pasta al ragù&amp;lt;/title&amp;gt;
    &amp;lt;ingredients&amp;gt;Pasta, pomodoro, ragù&amp;lt;/ingredients&amp;gt;
  &amp;lt;/recipe&amp;gt;
&amp;lt;/recipes&amp;gt;&lt;/pre&gt;

&lt;p&gt;Ovviamente non è completo di tutti i dati relativi alla ricetta, ma ho volutamente usato un XML “minimale” con lo scopo di capire la procedura più corretta per effettuarne il parsing con WinRT.&lt;/p&gt;

&lt;p&gt;L’inghippo che ho citato prima è&amp;#160; il mio tentativo di sfruttare il metodo &lt;strong&gt;Parse&lt;/strong&gt; della classe &lt;strong&gt;XDocument&lt;/strong&gt; (che permette di trasformare un XML piatto in una struttura dati complessa “navigabile” grazie a LINQ) è fallito miseramente. Ecco un estratto del codice che ho cercato di utilizzare:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public async void GetAllRecipes()
{
    StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(&amp;quot;Recipes.xml&amp;quot;);
    string xml = await FileIO.ReadTextAsync(file);
    XDocument doc = XDocument.Parse(xml);
    ...
  
}&lt;/pre&gt;

&lt;p&gt;In prima istanza ho recuperato il file &lt;strong&gt;Recipes.xml&lt;/strong&gt;, sfruttando il metodo &lt;strong&gt;GetFileAsync&lt;/strong&gt; citato poco fa. Dopodichè ho utilizzato un’altra classe di WinRT che permette di effettuare operazioni sui file, chiamata &lt;strong&gt;FileIO&lt;/strong&gt;: nel mio caso, ho usato il metodo &lt;strong&gt;ReadTextAsync&lt;/strong&gt; che, dato un oggetto di tipo &lt;strong&gt;StorageFile &lt;/strong&gt;(ovvero un file recuperato da uno dei vari storage disponibili), lo tratta come testuale e memorizza in una stringa il testo contenuto (ovviamente, anch’esso in maniera asincrona).&lt;/p&gt;

&lt;p&gt;Infine, ho utilizzato il metodo &lt;strong&gt;XDocument.Parse&lt;/strong&gt; su tale stringa: il risultato però, durante l’esecuzione, è un’eccezione di tipo &lt;strong&gt;ArgumentException, &lt;/strong&gt;con il messaggio &lt;em&gt;Data at the root level is invalid. Line 1, position 1&lt;/em&gt;, che solitamente sta a indicare un file XML non valido o con degli errori di sintassi. Una breve verifica però mi ha fatto capire che c’era qualcosa non andava, dato che il file XML&amp;#160; non conteneva alcun errore di sintassi.&lt;/p&gt;

&lt;p&gt;Il trucco sta nel leggere il file XML come stream e di sfruttare il metodo &lt;strong&gt;XDocument.Load&lt;/strong&gt; che, tra le varianti disponibili, accetta anche un oggetto di tipo &lt;strong&gt;Stream&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ecco il codice corretto:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;StorageFile storageFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(&amp;quot;Recipes.xml&amp;quot;);
var file = await storageFile.OpenAsync(FileAccessMode.Read);
Stream stream = file.AsStreamForRead();
XDocument doc = XDocument.Load(stream);


ApplicationContext.Current.Recipes = doc.Descendants(&amp;quot;recipes&amp;quot;).Elements(&amp;quot;recipe&amp;quot;).Select(x =&amp;gt; new Recipe
                                                              {
                                                                  Title = x.Element(&amp;quot;title&amp;quot;).Value,
                                                                  Ingredients = x.Element(&amp;quot;ingredients&amp;quot;).Value,
                                                                  Category = x.Element(&amp;quot;category&amp;quot;).Value
                                                              });&lt;/pre&gt;

&lt;p&gt;La differenza rispetto al codice precedente è che apriamo il file in lettura in maniera asincrona, tramite il metodo &lt;strong&gt;OpenAsync&lt;/strong&gt;, e lo convertiamo in uno stream sfruttando il metodo &lt;strong&gt;AsStreamForRead&lt;/strong&gt; esposto dall’oggetto &lt;strong&gt;file&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A questo punto possiamo inizializzare un’istanza della classe XDocument: le operazioni successive non differiscono in alcun modo da quelle che avremmo dovuto eseguire in un’applicazione Windows Phone o ASP.NET. Una volta in possesso del documento, ho recuperato tutti i nodi &lt;strong&gt;recipe&lt;/strong&gt; e ho trasformato ogni nodo in un oggetto di tipo &lt;strong&gt;Recipe&lt;/strong&gt;, che non fa altro che mappare 1 ad 1 le informazioni memorizzate nell’XML.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class Recipe
{
    public string Title { get; set; }
    public string Ingredients { get; set; }
}&lt;/pre&gt;

&lt;p&gt;Una volta in possesso di una collezione di oggetti di tipo &lt;strong&gt;Recipe &lt;/strong&gt;(nel mio caso, una &lt;strong&gt;List&amp;lt;Recipe&amp;gt;&lt;/strong&gt;) possiamo utilizzarla a piacimento nella nostra applicazione: ad esempio, possiamo utilizzarla come sorgente dati di ua ListView o di una GridView, esattamente come faremmo in un’applicazione Windows Phone.&lt;/p&gt;

&lt;p&gt;Ecco un esempio di ListView in XAML:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;ListView x:Name=&amp;quot;Recipes&amp;quot;&amp;gt;
    &amp;lt;ListView.ItemTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;StackPanel&amp;gt;
                &amp;lt;TextBlock Text=&amp;quot;{Binding Path=Title}&amp;quot; /&amp;gt;
                &amp;lt;TextBlock Text=&amp;quot;{Binding Path=Ingredients}&amp;quot; /&amp;gt;
            &amp;lt;/StackPanel&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/ListView.ItemTemplate&amp;gt;
&amp;lt;/ListView&amp;gt;&lt;/pre&gt;

&lt;p&gt;E il codice che si occupa di recuperare le ricette e visualizzare sfruttando la ListView:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public MainPage() 
{
    StorageFile storageFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(&amp;quot;Recipes.xml&amp;quot;);
    var file = await storageFile.OpenAsync(FileAccessMode.Read);
    Stream stream = file.AsStreamForRead();
    XDocument doc = XDocument.Load(stream);


    List&amp;lt;Recipe&amp;gt; recipes = doc.Descendants(&amp;quot;recipes&amp;quot;).Elements(&amp;quot;recipe&amp;quot;).Select(x =&amp;gt; new Recipe
                                                                          {
                                                                              Title = x.Element(&amp;quot;title&amp;quot;).Value,
                                                                              Ingredients = x.Element(&amp;quot;ingredients&amp;quot;).Value,
                                                                              Category = x.Element(&amp;quot;category&amp;quot;).Value
                                                                          }).ToList();
    Recipes.ItemsSource = recipes;
}&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=778" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Windows 8" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+8/default.aspx" /><category term="LINQ" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/LINQ/default.aspx" /><category term="XML" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/XML/default.aspx" /></entry><entry><title>Visualizzare immagini GIF in un’applicazione Windows Phone</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/18/visualizzare_2D00_immagini_2D00_gif_2D00_in_2D00_unapplicazione_2D00_windows_2D00_phone.aspx" /><id>/b/qmatteoq/archive/2012/02/18/visualizzare_2D00_immagini_2D00_gif_2D00_in_2D00_unapplicazione_2D00_windows_2D00_phone.aspx</id><published>2012-02-18T10:00:00Z</published><updated>2012-02-18T10:00:00Z</updated><content type="html">&lt;p&gt;L’altro giorno ho fatto due chiacchiere via Skype con &lt;a href="http://blogs.ugidotnet.org/ddl/Default.aspx"&gt;Nazareno Manco&lt;/a&gt;, un amico sviluppatore, che si è trovato ad affrontare un problema nello sviluppo di un’applicazione Windows Phone: la sua necessità era quella di recuperare delle immagini dal web, da visualizzare all’interno di una pagina. Il problema è che queste immagini erano in formato GIF, che non è supportato da Silverlight e, di conseguenza, da Windows Phone.&lt;/p&gt;  &lt;p&gt;Facendo una breve ricerca su Internet mi sono imbattuto &lt;a href="http://blogs.msdn.com/b/jaimer/archive/2010/11/23/working-with-gif-images-in-windows-phone.aspx"&gt;in questo post&lt;/a&gt; di Jaime Rodriguez, in cui viene citata la libreria &lt;a href="http://blogs.msdn.com/b/jaimer/archive/2010/11/23/working-with-gif-images-in-windows-phone.aspx"&gt;Image Tools&lt;/a&gt; per Silverlight, che offre una serie di controlli e converters che permettono di convertire in tempo reale un’immagine da un formato all’altro. Vediamo come utilizzarla per visualizzare imamgini GIF anche all’interno di un’applicazione Windows Phone.&lt;/p&gt;  &lt;p&gt;Innanzitutto dovete includere le varie DLL di cui è composta la libreria all’interno dell’applicazione: il modo più semplice è utilizzare NuGet, così che venga copiato il necessario in automatico.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML89ae30b.png"&gt;&lt;img title="SNAGHTML89ae30b" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTML89ae30b" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML89ae30b_thumb.png" width="547" height="367" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Dopodichè l’utilizzo di questa libreria si articola in due step:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;L’utilizzo del controllo &lt;strong&gt;AnimatedImage, &lt;/strong&gt;che va a sostiture il controllo &lt;strong&gt;Image&lt;/strong&gt; e funge da contenitore all’interno del quale verrà visualizzata l’immagine. &lt;/li&gt;    &lt;li&gt;L’utilizzo del converter &lt;strong&gt;ImageConverter&lt;/strong&gt;, che si occupa di fare la conversione da un formato all’altro. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Entrambe le classi fanno parte del namespace &lt;strong&gt;ImageTools.Controls&lt;/strong&gt;, che deve essere quindi dichiarato nello XAML:&lt;/p&gt;  &lt;pre&gt;xmlns:imagetools=&amp;quot;clr-namespace:ImageTools.Controls;assembly=ImageTools.Controls&amp;quot;&lt;/pre&gt;

&lt;p&gt;A questo punto potete dichiarare come risorsa (locale nella pagina o globale a livello di applicazione) il converter &lt;strong&gt;ImageConverter&lt;/strong&gt;, come nell’esempio:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;phone:PhoneApplicationPage.Resources&amp;gt;
    &amp;lt;imagetools:ImageConverter x:Key=&amp;quot;ImageConverter&amp;quot; /&amp;gt;
&amp;lt;/phone:PhoneApplicationPage.Resources&amp;gt;&lt;/pre&gt;

&lt;p&gt;Ora vi basta inserire il controllo &lt;strong&gt;AnimatedImage&lt;/strong&gt;, valorizzando la proprietà &lt;strong&gt;Source&lt;/strong&gt; con l’indirizzo dell’immagine GIF e applicando il converter appena dichiarato.&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;StackPanel&amp;gt;
    &amp;lt;imagetools:AnimatedImage x:Name=&amp;quot;Image&amp;quot; Source=&amp;quot;{Binding Path=ImageSource, Converter={StaticResource ImageConverter}}&amp;quot; /&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;p&gt;Nel codice, la proprietà &lt;strong&gt;ImageSource&lt;/strong&gt; è di tipo &lt;strong&gt;Uri&lt;/strong&gt; e punta all’indirizzo di un’immagine GIF di esempio:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;ImageSource = new Uri(&amp;quot;http://www.nonstopgifs.com/animated-gifs/games/games-animated-gif-002.gif&amp;quot;, UriKind.Absolute);&lt;/pre&gt;

&lt;p&gt;Il trucco per “far funzionare la magia” è l’utilizzo di uno dei decoder messi a disposizione dalla libreria Image Tools: è sufficiente registrarlo all’avvio dell’applicazione, specificando il formato dell’immagine che deve essere decodificato. Nel nostro esempio, dobbiamo utilizzare un &lt;strong&gt;GifDecoder&lt;/strong&gt;, che viene registrato come nell’esempio:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public MainPage()
{
    InitializeComponent();
    ImageTools.IO.Decoders.AddDecoder&amp;lt;GifDecoder&amp;gt;();
}&lt;/pre&gt;

&lt;p&gt;A questo punto, grazie ai due controlli utilizzati in precedenza qualsiasi immagine GIF che verrà caricata sarà automaticamente convertita in modo da essere visualizzata: la cosa interessante è che, grazie anche al controllo &lt;strong&gt;AnimatedImage, &lt;/strong&gt;sono supportate le GIF animate, per cui l’animazione verrà visualizzata correttamente.&lt;/p&gt;

&lt;p&gt;Di seguito trovate il link per scaricare il progetto di esempio di riferimento di questo post.&lt;/p&gt;

&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:2543b98d-8d59-4b79-a0d0-9c77bd33248a" class="wlWriterSmartContent" style="float:none;padding-bottom:0px;padding-top:0px;padding-left:0px;margin:0px;display:inline;padding-right:0px;"&gt;
  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/GifConversion.zip"&gt;Scarica il codice sorgente&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=776" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /></entry><entry><title>Nuovo requisito per la certificazione: Application Testability</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/18/nuovo_2D00_requisito_2D00_per_2D00_la_2D00_certificazione_2D00_application_2D00_testability.aspx" /><id>/b/qmatteoq/archive/2012/02/18/nuovo_2D00_requisito_2D00_per_2D00_la_2D00_certificazione_2D00_application_2D00_testability.aspx</id><published>2012-02-18T10:00:00Z</published><updated>2012-02-18T10:00:00Z</updated><content type="html">&lt;p&gt;Tra &lt;a href="http://msdn.microsoft.com/en-us/library/hh184840(v=vs.92).aspx"&gt;i requisiti tecnici&lt;/a&gt; indispensabili per passare la certificazione sul Marketplace è stata introdotta una nuova sezione, chiamata &lt;strong&gt;Application Testability. &lt;/strong&gt;In realtà, si tratta di un requisito che si dava già per scontato: evidentemente però non tutti gli sviluppatori ne tenevano conto e perciò Microsoft ha deciso di “ufficializzarlo”, includendolo nella documentazione.&lt;/p&gt;  &lt;p&gt;Cosa richiede questo requisito? Semplicemente che l’applicazione sia testabile in tutte le sue parti da parte dei tester del Marketplace: questo significa che dovete fornire tutti gli strumenti necessari per poter utilizzare tutte le funzionalità dell’applicazione. Ad esempio, se questa è legata ad un servizio che richiede delle credenziali (ad esempio, un client Twitter o Instapaper) dovete fornire delle credenziali di test; se l’applicazione è legata ad un client desktop (ad esempio, un tool di accesso remoto) dovete fornire anche un link per scaricare tale client.&lt;/p&gt;  &lt;p&gt;Dove specificare queste informazioni? Nell’ultimo step della certificazione, in cui si seleziona la modalità di pubblicazione (privata, automatica, manuale, ecc.), c’è un campo apposito dove lasciare delle note per il tester: questo è il posto giusto dove specificare credenziali, link per il download e quant’altro.&lt;/p&gt;  &lt;p&gt;Mi raccomando, non dimenticatevi! Se non fornite tutte le informazioni necessarie l’applicazione verrà sicuramente bocciata, costringendovi ad un nuovo “giro” di certificazione e allungando i tempi di pubblicazione della vostra applicazione.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=777" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /><category term="Marketplace" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Marketplace/default.aspx" /></entry><entry><title>Windows Phone SDK 7.1.1 rilasciato in versione finale</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/17/windows_2D00_phone_2D00_sdk_2D00_7.1.1_2D00_rilasciato_2D00_in_2D00_versione_2D00_finale.aspx" /><id>/b/qmatteoq/archive/2012/02/17/windows_2D00_phone_2D00_sdk_2D00_7.1.1_2D00_rilasciato_2D00_in_2D00_versione_2D00_finale.aspx</id><published>2012-02-17T10:00:00Z</published><updated>2012-02-17T10:00:00Z</updated><content type="html">&lt;p&gt;Dopo non molto tempo dalla prima release dell’SDK 7.1.1 per Windows Phone in versione CTP, ecco arrivare la versione finale, dedicata principalmente al testing delle applicazioni con i nuovi device di fascia bassa. Questa SDK contiene infatti un nuovo emulatore, in grado di simulare sia i device tradizionali dotati di 512 MB di RAM, sia quelli più economici dotati di 256 MB. Come già ricordato nel post precedente, la ridotta quantità di memoria non è l’unica differenza rispetto ai device tradizionali: è però l’unico aspetto che ha un impatto sullo sviluppo di applicazioni, dato che quelle troppo onerose in termini di memoria consumata non saranno in grado di funzionare.&lt;/p&gt;  &lt;p&gt;Per una panoramica completa su questa versione e sulle tecniche per ottimizzare il consumo di memoria delle applicazioni vi rimando &lt;a href="http://www.qmatteoq.com/blog/post/qualche-articolo-interessante-sul-blog-msdn-sdk-7.1.1-e-web-api"&gt;ai due articoli da me scritti che sono stati pubblicati poco tempo fa&lt;/a&gt; sul blog MSDN.&lt;/p&gt;  &lt;p&gt;Quali sono le principali differenze rispetto alla versione CTP di qualche tempo fa?&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Trattandosi di una versione finale, questa SDK &lt;strong&gt;ha la licenza go live: &lt;/strong&gt;può essere usata perciò per sviluppare applicazioni che verranno pubblicate sul Marketplace. &lt;/li&gt;    &lt;li&gt;Ora l’SDK è localizzato in 10 lingue, al contrario della CTP che era disponibile solo in inglese. &lt;/li&gt;    &lt;li&gt;Grazie a questa versione dell’SDK ora &lt;strong&gt;l’emulatore è compatibile con Windows 8: &lt;/strong&gt;è sempre stato possibile installare i tool di sviluppo sulla Consumer Preview del nuovo OS di Microsoft (anche se con Visual Studio 2010, la versione 11 non è ancora supportata) ma, a causa dell’incompatibilità dell’emulatore, era possibile effettuare i test solo su un device reale. Con questa nuova versione l’emulatore torna ad essere funzionante e, di conseguenza, potete fare come il sottoscritto e sbarazzarvi di Windows 7 per iniziare ad usare solamente Windows 8 &lt;img class="wlEmoticon wlEmoticon-smile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Smile" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/wlEmoticon-smile_2_75.png" /&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Potete scaricare la nuova versione all’indirizzo &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=29233"&gt;http://www.microsoft.com/download/en/details.aspx?id=29233&lt;/a&gt;: vi ricordo che non si tratta di una nuova versione dell’SDK ma di un aggiornamento, che va ad installarsi sopra la versione 7.1 dell’SDK. Non è necessario perciò disinstallare la versione precedente.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=775" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /></entry><entry><title>I primi passi con PhoneGap: accesso ai dati tramite Web API di MVC 4</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/14/i_2D00_primi_2D00_passi_2D00_con_2D00_phonegap_2D00_accesso_2D00_ai_2D00_dati_2D00_tramite_2D00_web_2D00_api_2D00_di_2D00_mvc_2D00_4.aspx" /><id>/b/qmatteoq/archive/2012/02/14/i_2D00_primi_2D00_passi_2D00_con_2D00_phonegap_2D00_accesso_2D00_ai_2D00_dati_2D00_tramite_2D00_web_2D00_api_2D00_di_2D00_mvc_2D00_4.aspx</id><published>2012-02-14T10:00:00Z</published><updated>2012-02-14T10:00:00Z</updated><content type="html">&lt;p&gt;Come promesso la volta scorsa, avevo intenzione di scrivere un post con lo scopo di mostrare come raggiungere lo stesso obiettivo dell’altra volta (consumare un servizio REST sfruttando jQuery) utilizzando però un servizio realizzato da noi invece di uno già esistente (ricordate &lt;a href="http://baconipsum.com/"&gt;Bacom Ipsum&lt;/a&gt;)?&lt;/p&gt;  &lt;p&gt;Nel momento in cui ho scritto quel post erano due le strade che stavo valutando utilizzando le tecnologie Microsoft:&amp;#160; WCF Data Services oppure ASP.NET MVC. La prima è la soluzione più adatta, dato che WCF è una tecnologia che nasce espressamente per gestire servizi, ovvero tutte quelle applicazioni che tipicamente non richiedono un’interazione umana ma si limitano a esporre dati e/o operazioni che vengono poi consumate da altre applicazioni.&lt;/p&gt;  &lt;p&gt;I servizi WCF non sono però così semplici da realizzare e, anche utilizzando la variante Data Services con il supporto al protocollo OData, non è offerto il supporto nativo a JSON come formato in cui esporre i dati (ma bisogna ricorrere ad alcuni espedienti, &lt;a href="http://blogs.msdn.com/b/writingdata_services/archive/2011/02/25/getting-json-out-of-wcf-data-services.aspx"&gt;come quelli spiegati in questo post&lt;/a&gt;); supporto che invece è fornito da ASP.NET MVC, grazie alla possibilità di restituire una &lt;strong&gt;JsonResult&lt;/strong&gt; come risultato di una Action definita in un controller.&lt;/p&gt;  &lt;p&gt;ASP.NET MVC però non sempre è la tecnologia migliore, dato che il suo scopo, al contrario di WCF, è quello di realizzare applicazioni che sappiano rispondere all’interazione umana: siti, form, intranet, ecc. Se abbiamo già un sito realizzato con questa tecnologia e dobbiamo esporre alcune informazioni tramite servizi, allora può essere una buona soluzione quella di appoggiarsi direttamente a ASP.NET MVC e “ospitarli” in un controller. Se però dobbiamo mettere in piedi un sito basato su ASP.NET MVC solamente per esporre questi servizi, allora il gioco potrebbe non valere la candela.&lt;/p&gt;  &lt;p&gt;Settimana scorsa è stata presentata ufficialmente la prima beta di ASP.NET MVC 4, che tra le altre cose ha introdotto proprio una novità che fa al caso nostro: le Web API. Tale tecnologia era conosciuta come WCF Web API e si trattava di &lt;a href="http://wcf.codeplex.com/wikipage?title=WCF%20HTTP"&gt;un progetto open source ospitato su Codeplex&lt;/a&gt;, che ora è stata integrata all’interno di ASP.NET MVC e ha preso il nome ufficiale di &lt;a href="http://weblogs.asp.net/jgalloway/archive/2012/02/16/asp-net-4-beta-released.aspx"&gt;ASP.NET Web API&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Questa tecnologia cerca di coniugare, in maniera più semplice, il meglio di entrambi i mondi: permette di realizzare servizi, usando però le stesse feature di ASP.NET MVC (funzionalità definite all’interno di un controller, routing, supporto a JSON, ecc.).&lt;/p&gt;  &lt;p&gt;Quale miglior occasione per sperimentare con questa nuova tecnologia per realizzare un servizio da far consumare alla nostra applicazione Windows Phone realizzata con PhoneGap?&lt;/p&gt;  &lt;h3&gt;Cosa ci serve?&lt;/h3&gt;  &lt;p&gt;Per poter utilizzare Web API è necessario installare la beta di MVC 4, tramite la Web Platform Installer, la piattaforma di Microsoft che semplifica l’installazione di tool e prodotti legati al mondo web. Collegatevi perciò alla pagina &lt;a href="http://www.asp.net/mvc/mvc4"&gt;http://www.asp.net/mvc/mvc4&lt;/a&gt;, cliccate sul link &lt;strong&gt;Install ASP.NET MVC 4 Beta&lt;/strong&gt; e seguite le istruzioni.&lt;/p&gt;  &lt;p&gt;Una volta completata l’operazione, dovreste trovare in Visual Studio un nuovo template nella sezione Web, chiamato &lt;strong&gt;ASP.NET MVC 4 Web Application&lt;/strong&gt;. E’ quello che andremo ad utilizzare per realizzare il nostro servizio.&lt;/p&gt;  &lt;h3&gt;La nostra prima applicazione Web API&lt;/h3&gt;  &lt;p&gt;Dopo aver scelto di creare un nuovo progetto di tipo ASP.NET MVC 4, noteremo subito una differenza con MVC 3: i template a disposizione sono molto più numerosi. Tra questi, ci sarà anche quello che fa al caso nostro: Web API.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML47c9c36.png"&gt;&lt;img title="SNAGHTML47c9c36" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTML47c9c36" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML47c9c36_thumb.png" width="461" height="417" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Selezioniamolo e diamo OK e verrà creato un progetto con la stessa identica struttura di un sito ASP.NET MVC: si tratta infatti di un progetto ibrido, che ospita sia un sito web con un template di default e alcune pagine fittizie, sia le Web Api. Se apriamo infatti la cartella &lt;strong&gt;Controllers, &lt;/strong&gt;troveremo due classi già pronte: &lt;strong&gt;HomeController&lt;/strong&gt; è un controller “standard”, che eredita dalla classe &lt;strong&gt;Controller&lt;/strong&gt; e funge da controller per la vista web; &lt;strong&gt;ValuesController&lt;/strong&gt; è invece il controller utilizzato per il servizio ed eredita dalla classe &lt;strong&gt;ApiController&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Se guardate il contenuto di questa classe noterete subito una prima differenza rispetto ai controller standard di MVC: le varie funzioni definite al suo interno non restituiscono una &lt;strong&gt;ActionResult&lt;/strong&gt;, ma void o un tipo specifico (ad esempio, string), a seconda della funzione.&lt;/p&gt;  &lt;p&gt;Questo perchè i servizi Web API sono servizi REST e, sfruttando il protocollo HTTP, rispondono semplicemente ai comandi resi disponibili da tale protocollo: GET, POST, PUT e DELETE. Le WebAPI sfruttano perciò una convenzione tale per cui è sufficiente che i metodi abbiano i nomi dei comandi perchè vengano invocati in seguito ad una richiesta HTTP con quel comando.&lt;/p&gt;  &lt;p&gt;Le Web API sfruttano anche le stesse convenzioni di ASP.NET MVC per quanto riguarda il routing: di default, le API vengono esposte all’URL&lt;strong&gt; /api/nomedelcontroller&lt;/strong&gt;, dove il nome del controller è il nome della classe esclusa la parola Controller (nel controller di default &lt;strong&gt;ValuesController&lt;/strong&gt;, l’URL ad esempio è &lt;strong&gt;/api/values&lt;/strong&gt;).&lt;/p&gt;  &lt;p&gt;Le regole del routing, così come per i controller tradizionali che servono le pagine web, sono definite nel file &lt;strong&gt;global.asax.cs&lt;/strong&gt; del progetto: è qui che dobbiamo agire, se, ad esempio, vogliamo cambiare la prima parte dell’URL (&lt;strong&gt;/api&lt;/strong&gt;) oppure definire delle regole di routing più complesse.&lt;/p&gt;  &lt;h3&gt;Creiamo il nostro controller&lt;/h3&gt;  &lt;p&gt;Invece di utilizzare il controller di default &lt;strong&gt;ValuesController&lt;/strong&gt;, andremo a crearne uno personalizzato: facciamo clic con il tasto destro sulla cartella &lt;strong&gt;Controllers, &lt;/strong&gt;diamo un nome al controller (nell’esempio che seguirà l’ho chiamato &lt;strong&gt;ComicsController&lt;/strong&gt;, dato che restituirà una serie di nomi di personaggi dei fumetti) e selezioniamo come template &lt;strong&gt;API Controller with empty read / write actions.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML4d2179e.png"&gt;&lt;img title="SNAGHTML4d2179e" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTML4d2179e" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML4d2179e_thumb.png" width="449" height="292" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Avremo a disposizione un controller con la stessa struttura di quello che abbiamo visto in precedenza: la differenza è che questa volta i servizi verranno esposti tramite l’URL &lt;strong&gt;/api/comics&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Il controller che andremo a realizzare è semplicissimo: creeremo un array di stringhe contenente un elenco di personaggi dei fumetti, dopodichè definiremo una funzione Get generica (che restituisca l’intera lista), e una funzione Get specifica che, accettando un parametro in ingresso, permette di ritornare un elemento specifico della lista.&lt;/p&gt;  &lt;pre class="brush: csharp; ruler: true;"&gt;public class ComicsController : ApiController
{
   private string[] heroes = new string[] {&amp;quot;Iron Man&amp;quot;, &amp;quot;Wolverine&amp;quot;, &amp;quot;Hulk&amp;quot;, &amp;quot;Thor&amp;quot;, &amp;quot;Captain America&amp;quot;};


   // GET /api/comics
   public IEnumerable&amp;lt;string&amp;gt; Get()
   {
       return heroes;
   }

   // GET /api/comics/5
   public string Get(int id)
   {
       return heroes[id];
   }
}&lt;/pre&gt;

&lt;p&gt;Testare il funzionamento è molto semplice: lanciamo il debug del nostro progetto (magari avendo preventivamente selezionato di ospitare il sito su IIS Express tramite l’apposita opzione disponibile quando si fa clic con il tasto destro sul progetto in Solution Explorer); verrà caricato di default il sito “fittizio” generato dal template. Ci basta ora inserire l’URL del nostro servizio, come definito nel routing, per vedere il risultato (ad esempio, &lt;strong&gt;http://localhost:7392/api/comics&lt;/strong&gt;, dove 7392 è la porta assegnata da IIS Express alla nostra applicazione). &lt;/p&gt;

&lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML4ef61b8.png"&gt;&lt;img title="SNAGHTML4ef61b8" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTML4ef61b8" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML4ef61b8_thumb.png" width="820" height="221" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aggiungendo l’identificativo all’URL dopo lo /, ecco che verrà restituito uno specifico elemento della lista:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML4fcdaaf.png"&gt;&lt;img title="SNAGHTML4fcdaaf" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTML4fcdaaf" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML4fcdaaf_thumb.png" width="651" height="143" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;L’applicazione Windows Phone con PhoneGap&lt;/h3&gt;

&lt;p&gt;Dal punto di vista dell’applicazione Windows Phone realizzata con PhoneGap nulla cambia rispetto all’esempio del post precedente, se non l’indirizzo a cui far puntare la chiamate del metodo &lt;strong&gt;getJSON:&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: js; ruler: true;"&gt;$(&amp;quot;#btnCall&amp;quot;).click(function () {
    $.support.cors = true;
    $.getJSON(&amp;quot;http://localhost:7392/api/comics/&amp;quot;, function (data) {
        $.each(data, function (index, element) {
            $(&amp;quot;#result&amp;quot;).append(element + &amp;quot;&amp;lt;br /&amp;gt;&amp;quot;);
        });
    });
});&lt;/pre&gt;

&lt;p&gt;Il risultato sarà il medesimo della volta scorsa, ovvero gli elementi contenuti all’interno della lista verranno mostrati a video:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_4_6.png"&gt;&lt;img title="image" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="image" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_thumb_1_7.png" width="199" height="332" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;Where in the world is JSON?&lt;/h3&gt;

&lt;p&gt;Se siete state attenti, avrete notato qualcosa di anomalo: quando avete chiamato il servizio appena creato con il browser, i dati vi sono stati restituiti nel formato XML. Eppure il metodo getJSON di jQuery è stato in grado di elaborare i dati e mostrarli a schermo: questo è stato possibile grazie ad una delle funzionalità più interessanti delle Web API, ovvero la possibilità per i servizi di restituire in automatico dati XML o JSON a seconda dell’header della richiesta HTTP. Volendo, è possibile inoltre creare dei formatter custom per restituire i dati in altri formati.&lt;/p&gt;

&lt;p&gt;Possiamo avere una prova di questo meccanismo utilizzando un tool come &lt;a href="http://fiddler2.com/fiddler2/"&gt;Fiddler&lt;/a&gt;, che ci permette di intercettare il traffico di rete: qui sotto potete vedere due screenshot, il primo relativo alla chiamata effettuata tramite il browser e il secondo a quella fatta tramite jQuery e l’applicazione Windows Phone.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_6.png"&gt;&lt;img title="image" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="image" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_thumb_2_1.png" width="1024" height="118" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_8.png"&gt;&lt;img title="image" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="image" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_thumb_3_1.png" width="1024" height="142" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Come potete vedere, in base al valore dell’header &lt;strong&gt;Accept&lt;/strong&gt; della chiamata HTTP il nostro servizio è stato in grado di restituire i dati nel formato richiesto.&lt;/p&gt;

&lt;h3&gt;In conclusione&lt;/h3&gt;

&lt;p&gt;Abbiamo concluso una panoramica molto semplice su Windows Phone, PhoneGap e accesso ai dati. Magari in futuro ritorneremo sull’argomento, parlando più approfonditamente dell’integrazione tra PhoneGap e le API native di Windows Phone. Come sempre, di seguito trovate il link per scaricare il codice sorgente dell’applicazione basata su Web API che abbiamo realizzato (per quanto riguarda quella Windows Phone potete riutilizzare la stessa del post precedente).&lt;/p&gt;

&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:b78cacdb-57b3-413c-9dd9-b7cc25c2e64d" class="wlWriterSmartContent" style="float:none;padding-bottom:0px;padding-top:0px;padding-left:0px;margin:0px;display:inline;padding-right:0px;"&gt;
  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/WebAPI.zip"&gt;Scarica il codice sorgente&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=773" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /><category term="PhoneGap" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/PhoneGap/default.aspx" /><category term="MVC" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/MVC/default.aspx" /><category term="Web API" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Web+API/default.aspx" /></entry><entry><title>I primi passi con PhoneGap: accesso ai dati tramite un servizio REST – Parte 1</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/12/i_2D00_primi_2D00_passi_2D00_con_2D00_phonegap_2D00_accesso_2D00_ai_2D00_dati_2D00_tramite_2D00_un_2D00_servizio_2D00_rest_2D00_parte_2D00_1.aspx" /><id>/b/qmatteoq/archive/2012/02/12/i_2D00_primi_2D00_passi_2D00_con_2D00_phonegap_2D00_accesso_2D00_ai_2D00_dati_2D00_tramite_2D00_un_2D00_servizio_2D00_rest_2D00_parte_2D00_1.aspx</id><published>2012-02-12T10:00:00Z</published><updated>2012-02-12T10:00:00Z</updated><content type="html">&lt;p&gt;Dopo aver visto qualche semplice esempio di utilizzo di PhoneGap, vediamo ora qualcosa di più complesso ma anche più utile: come importare dati esposti da un servizio. In questo post non andremo ad utilizzare le funzionalità specifiche di PhoneGap: quello che faremo sarà consumare un servizio REST, esattamente come faremmo con un’applicazione web tradizionale. C’è però qualche accorgimento da adottare per far si che il tutto funzioni anche su Windows Phone, a causa di qualche problemino di compatibilità tra jQuery e PhoneGap per Windows Phone.&lt;/p&gt;  &lt;p&gt;Ma andiamo per gradi.&lt;/p&gt;  &lt;h3&gt;I servizi REST&lt;/h3&gt;  &lt;p&gt;I servizi di tipo REST sono una realtà sempre più diffusa, grazie anche alla semplicità di utilizzo indipendentemente dalla tecnologia utilizzata per “consumarli”. Al contrario dei web service tradizionali (basati su SOAP), i servizi REST si basano sul solo protocollo HTTP e si rifanno al concetto di risorsa più che di operazione. Cosa significa? Che un web service tipicamente espone una serie di operazioni, le quali vengono interpretate e utilizzate dal client grazie al protocollo SOAP; i servizi REST invece mappano questa richiesta sotto forma di risorsa, usando la normale notazione degli URL del protocollo HTTP. Ecco perciò che un’ipotetica funzione per recuperare le informazioni di un utente specifico verrebbe tradotta in un web service con il metodo &lt;strong&gt;getUser(int id),&lt;/strong&gt; mentre in un servizio REST si tratterebbe semplicemente di richiamare l’URL &lt;strong&gt;/User/5 &lt;/strong&gt;(dove 5 è l’ipotetico id di un utente).&lt;/p&gt;  &lt;p&gt;Il vantaggio di questo meccanismo è evidente: lato client per consumare un web service è necessaria una libreria che sia in grado di tradurre la chiamata SOAP in un qualcosa di comprensibile per il linguaggio che stiamo utilizzando, a meno che non vogliamo elaborare manualmente le chiamate SOAP di richiesta e di risposta. E’ il caso ad esempio di Visual Studio: quando importiamo un servizio tramite l’opzione &lt;strong&gt;Add Service Reference&lt;/strong&gt; viene generata una classe proxy, che non è altro che la rappresentazione sotto forma di classe in C# o VB.NET del servizio.&lt;/p&gt;  &lt;p&gt;Con i servizi REST tutto ciò non è necessario: è sufficiente chiamare l’URL ed elaborare la risposta (tipicamente un XML o un JSON). Proprio per questo motivo, i servizi REST sono sicuramente la scelta più utilizzata nel mondo Javascript, in quanto non richiedono nessun tool o libreria particolari per essere utilizzati. E’ sufficiente effettuare una semplice chiamata HTTP verso l’URL ed elaborare la risposta (operazione resa ancora più semplice da librerie come jQuery, come vedremo tra poco).&lt;/p&gt;  &lt;p&gt;Per il nostro esempio utilizzeremo un servizio JSON già pronto, nei prossimi post vedremo invece come crearne uno sfruttando ASP.NET MVC. Il servizio scelto per questo tutorial è quello offerto da, rullo di tamburi, &lt;a href="http://baconipsum.com"&gt;Bacon Ipsum&lt;/a&gt;, fantastico sito che ho scoperto grazie ad un tweet di &lt;a href="http://www.geniodelmale.info"&gt;Lorenzo&lt;/a&gt;. Avete presente &lt;a href="http://www.lipsum.com/"&gt;Lorem Ipsum&lt;/a&gt;, celebre sito utilizzato per la generazione di testi casuali? Questi testi solitamente vengono utilizzati in fase di montaggio di un prototipo o di un sito Internet, per dare l’idea dell’ingombro che occuperanno i testi. Bacon Ipsum fa la stessa cosa, ma sostituendo alle parole latine i nomi di vari tipi e tagli di carne (come steak, bacon, beef, ecc.). &lt;img class="wlEmoticon wlEmoticon-smile" style="border-top-style:none;border-left-style:none;border-bottom-style:none;border-right-style:none;" alt="Smile" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/wlEmoticon-smile_2_73.png" /&gt;&lt;/p&gt;  &lt;p&gt;Al di là della goliardia, questo sito fa al caso nostro perchè espone proprio un servizio REST che permette di recuperare testi generati a caso in formato JSON.&lt;/p&gt;  &lt;h3&gt;Creiamo il progetto&lt;/h3&gt;  &lt;p&gt;Non sto qui a ripetere punto per punto i passi per creare un progetto PhoneGap per Windows Phone, dato che li abbiamo già visti nel post precedente: ne approfitto solamente per segnalarvi che, rispetto al post precedente, è stata rilasciata una nuova versione di PhoneGap, la 1.4.1 per la precisione. Il procedimento per installarla è sempre lo stesso: &lt;a href="http://phonegap.com/download/"&gt;scaricate il pacchetto&lt;/a&gt; e copiate il file &lt;strong&gt;PhoneGapStarter.zip&lt;/strong&gt; nella cartella dei template di Visual Studio. Dopo aver creato un nuovo progetto PhoneGap, vi ritroverete la struttura che ormai dovrebbe esservi famigliare: andremo ad agire all’interno della cartella &lt;strong&gt;www&lt;/strong&gt; per consumare il servizio e mostrare a video i testi generati a caso.&lt;/p&gt;  &lt;p&gt;La prima cosa da fare è includere &lt;a href="http://www.jquery.com"&gt;jQuery&lt;/a&gt;, la celebre libreria che semplifica la vita a chi sviluppa in Javascript, offrendo una sintassi più semplice e il supporto nativo per alcune delle funzionalità più utilizzate con questo linguaggio, come le chiamate asincrone e il parsing di dati JSON. Abbiamo due possibilità:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Utilizzare una CDN (Content Delivery Network), ovvero appoggiarci ad uno dei tanti servizi che ospitano in maniera distribuita jQuery. Microsoft stessa &lt;a href="http://www.asp.net/ajaxlibrary/cdn.ashx#jQuery_Releases_on_the_CDN_0"&gt;ci offre questa opportunità&lt;/a&gt;, mettendoci a disposizione sia la versione tradizionale per lo sviluppo che quella minificata per la distribuzione. &lt;/li&gt;    &lt;li&gt;Scaricare jQuery dal sito ufficiale &lt;a href="http://www.jquery.com"&gt;http://www.jquery.com&lt;/a&gt; e includere la libreria all’interno della cartella &lt;strong&gt;www&lt;/strong&gt; di PhoneGap. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;L’unico vantaggio di utilizzare una versione locale di jQuery è che saremo in grado di utilizzarla anche in assenza di connettività: dato che però la nostra demo ruota attorno all’utilizzo di un servizio REST esposto su Internet, direi che possiamo tranquillamente utilizzare la CDN di Microsoft tramite l’URL &lt;a href="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.js"&gt;http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.js&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ci basta perciò inserire nella sezione &lt;strong&gt;&amp;lt;head&amp;gt;&lt;/strong&gt; del file &lt;strong&gt;index.html&lt;/strong&gt; la seguente riga:&lt;/p&gt;  &lt;pre class="brush: xml; ruler: true;"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Aggiornamento: &lt;/strong&gt;il buon &lt;a href="http://cradle.aspitalia.com"&gt;Marco De Sanctis&lt;/a&gt; mi ha fatto giustamente notare che l’utilizzo di una CDN su un’applicazione mobile non è consigliata, in quanto se per un problema di sicurezza un hacker dovesse riuscire a “mettersi” in mezzo alla CDN sarebbe poi in grado, grazie alle API di PhoneGap, di accedere ai dati del vostro telefono. Il consiglio è quindi quello di scaricare jQuery in locale (tramite NuGet o direttamente dal &lt;a href="http://www.jquery.com"&gt;sito ufficiale&lt;/a&gt;) e includerlo nella cartella &lt;strong&gt;www&lt;/strong&gt;, dopodichè aggiungere una referenza alla copia locale invece che alla CDN, come nell’esempio:&lt;/p&gt;

&lt;pre class="brush: js; ruler: true;"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;scripts/jquery-1.7.1.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;A questo punto siamo pronti per sfruttare le feature di jQuery per interagire con il servizio REST di Bacon Ipsum. Nel prossimo post vedremo come fare!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=771" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /><category term="HTML 5" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/HTML+5/default.aspx" /><category term="PhoneGap" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/PhoneGap/default.aspx" /><category term="JQuery" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/JQuery/default.aspx" /></entry><entry><title>I primi passi con PhoneGap per Windows Phone: creiamo il primo progetto</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/11/i_2D00_primi_2D00_passi_2D00_con_2D00_phonegap_2D00_per_2D00_windows_2D00_phone_2D00_creiamo_2D00_il_2D00_primo_2D00_progetto.aspx" /><id>/b/qmatteoq/archive/2012/02/11/i_2D00_primi_2D00_passi_2D00_con_2D00_phonegap_2D00_per_2D00_windows_2D00_phone_2D00_creiamo_2D00_il_2D00_primo_2D00_progetto.aspx</id><published>2012-02-11T10:00:00Z</published><updated>2012-02-11T10:00:00Z</updated><content type="html">&lt;p&gt;Nel post precedente abbiamo iniziato a capire che cos’è PhoneGap e cosa significa al giorno d’oggi sviluppare un’applicazione mobile cross-platform. Ora iniziamo a “sporcarci le mani” e vediamo come iniziare a lavorare con PhoneGap, creando il nostro primo progetto e scrivendo qualche riga di codice.&lt;/p&gt;  &lt;h3&gt;Installare PhoneGap&lt;/h3&gt;  &lt;p&gt;Innanzitutto occorre scaricare il pacchetto di PhoneGap dal sito ufficiale all’indirizzo &lt;a title="http://phonegap.com/" href="http://phonegap.com/"&gt;http://phonegap.com/&lt;/a&gt;. Il package contiene le librerie per tutte le principali piattaforme: la versione Windows Phone si presenta come un template per Visual Studio, incluso nel file &lt;strong&gt;PhoneGapStarter.zip&lt;/strong&gt;, da copiare all’interno della cartella &lt;strong&gt;C:\Users\[USERNAME]\Documents\Visual Studio 2010\Templates\ProjectTemplates\Silverlight for Windows Phone&lt;/strong&gt;, dove &lt;strong&gt;[USERNAME]&lt;/strong&gt; è ovviamente il nome del vostro account utente.&lt;/p&gt;  &lt;p&gt;Una volta fatta questa operazione, se avviate Visual Studio e scegliete di creare un nuovo progetto, nella sezione &lt;strong&gt;Visual C#&lt;/strong&gt; (sia per le versioni Express che per le versioni a pagamento) troverete un nuovo template chiamato &lt;strong&gt;PhoneGapStarter&lt;/strong&gt;: date un nome al progetto, premete Ok e Visual Studio inizierà la creazione includendo tutti i file necessari a PhoneGap.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML53b5d18.png"&gt;&lt;img title="SNAGHTML53b5d18" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTML53b5d18" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTML53b5d18_thumb.png" width="628" height="382" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;La struttura di un progetto PhoneGap&lt;/h3&gt;  &lt;p&gt;Il progetto PhoneGap, rispetto ad un progetto tradizionale Windows Phone, include una serie di file e cartelle in più, che sono quelle utilizzate da PhoneGap. Quella più importante è la cartella &lt;strong&gt;www&lt;/strong&gt;, che contiene l’applicazione web e propria e, di default, contiene:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;il file &lt;strong&gt;index.html, &lt;/strong&gt;che è la pagina che viene caricata all’avvio &lt;/li&gt;    &lt;li&gt;il file &lt;strong&gt;master.css&lt;/strong&gt;, che è il foglio di stile di default che viene utilizzato &lt;/li&gt;    &lt;li&gt;il file &lt;strong&gt;phonegap-1-3-0.js&lt;/strong&gt;, che è la libreria Javascript che funge da wrapper verso le chiamate native della piattaforma e con la quale andrete ad interagire per sfruttare le funzionalità native del device. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;L’applicazione PhoneGap è a tutti gli effetti una vera e propria applicazione web, per cui all’interno&amp;#160; di questa cartella potete inserire tutte le risorse che volete, incluse librerie come jQuery o Knockout.js, molto conosciute nell’ambito dello sviluppo web. In automatico, all’avvio, PhoneGap compilerà un file chiamato &lt;strong&gt;GapSourceDictionary.xml&lt;/strong&gt; includendo i riferimenti a tutte queste risorse, per poi poterle utilizzare.&lt;/p&gt;  &lt;h3&gt;La struttura della pagina index.html&lt;/h3&gt;  &lt;p&gt;Il file &lt;strong&gt;index.html&lt;/strong&gt; non è nient’altro che una normalissima pagina HTML5 (lo riconoscete dal doctype), con già inclusi al suo interno gli script e i fogli di stile standard di PhoneGap che vi ho elencato prima.&lt;/p&gt;  &lt;p&gt;In più, la pagina include la sottoscrizione, tramite un event listener di Javascript, all’evento &lt;strong&gt;deviceready&lt;/strong&gt;, che viene invocato da PhoneGap nel momento in cui l’applicazione è stata inizializzata ed è pronta a interagire con l’utente. Tale sottoscrizione viene gestita dalla funzione &lt;strong&gt;onDeviceReady&lt;/strong&gt; (definita poco sotto), in cui potete includere il codice che volete eseguire all’avvio dell’applicazione. Di default, questa funzione contiene semplicemente due righe di codice Javascript per:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Mostrare il classico Hello World indicando anche la versione di PhoneGap in uso sfruttando la funzione &lt;strong&gt;&lt;em&gt;window.device.phonegap&lt;/em&gt;&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Dato che fare debug di Javascript in una pagina che gira all’interno di un browser mobile non è così agevole come con un browser tradizionale, PhoneGap include una funzione Javascript che permette di scrivere nella Output Window di Visual Studio, che si chiama &lt;em&gt;&lt;strong&gt;console.log&lt;/strong&gt;. &lt;/em&gt;Di default, il progetto di PhoneGap include la scrittura di un messaggio di prova nella Output Window.         &lt;br /&gt;&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Mostriamo una MessageBox&lt;/h3&gt;  &lt;p&gt;Iniziamo a mettere mano al progetto con un esempio molto semplice: mostriamo a video una MessageBox nel momento in cui l’utente fa click su un pulsante. La parte di rendering del pulsante e di gestione del click viene affidata ad HTML e Javascript standard; la visualizzazione dell’alert invece verrà fatta utilizzando una funzione proprietaria di PhoneGap.&lt;/p&gt;  &lt;p&gt;Vediamo l’HTML.&lt;/p&gt;  &lt;pre class="brush: xml; ruler: true;"&gt;&amp;lt;body&amp;gt;
    &amp;lt;input onclick=&amp;quot;onClick()&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Click me&amp;quot; /&amp;gt;
&amp;lt;/body&amp;gt;&lt;/pre&gt;

&lt;p&gt;La pagina è composta da un semplice div, a cui abbiamo dato l’id &lt;strong&gt;welcomeMsg&lt;/strong&gt; per poterlo identificare in Javascript, e un tag input, che rappresenta il nostro bottone, del quale gestiremo l’evento &lt;strong&gt;onclick&lt;/strong&gt; tramite la funzione &lt;strong&gt;onClick()&lt;/strong&gt;, che è così definita:&lt;/p&gt;

&lt;pre class="brush: js; ruler: true;"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
    function onClick() {
        navigator.notification.alert(&amp;quot;This is a message box&amp;quot;);
    }
&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;Qui entra in gioco PhoneGap: la funzione &lt;strong&gt;navigator.notification.alert&lt;/strong&gt; provvede a interfacciarsi con le API native di Windows Phone e a mostrare una MessageBox con il testo che viene passato come parametro della funzione. Lanciamo l’applicazione tramite il debugger di Visual Studio, facciamo clic sul pulsante e vedrete comparire la MessageBox nativa di Windows Phone con il testo che avete scelto.&lt;/p&gt;

&lt;h3&gt;In conclusione&lt;/h3&gt;

&lt;p&gt;In questo post abbiamo visto un esempio molto semplice: nel prossimo post vedremo qualcosa di più approfondito, che ci permettà di sfruttare più a fondo le potenzialità di Windows Phone. In allegato, trovate il codice sorgente del semplice esempio realizzato in questo post.&lt;/p&gt;

&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:61caeba9-6f4f-4a59-a43e-46d7341ecaec" class="wlWriterSmartContent" style="float:none;padding-bottom:0px;padding-top:0px;padding-left:0px;margin:0px;display:inline;padding-right:0px;"&gt;
  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/PhoneGapStarter1.zip"&gt;Scarica il codice sorgente&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=770" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /><category term="HTML 5" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/HTML+5/default.aspx" /><category term="Javascript" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Javascript/default.aspx" /><category term="PhoneGap" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/PhoneGap/default.aspx" /></entry><entry><title>I primi passi con PhoneGap per Windows Phone</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/10/i_2D00_primi_2D00_passi_2D00_con_2D00_phonegap_2D00_per_2D00_windows_2D00_phone.aspx" /><id>/b/qmatteoq/archive/2012/02/10/i_2D00_primi_2D00_passi_2D00_con_2D00_phonegap_2D00_per_2D00_windows_2D00_phone.aspx</id><published>2012-02-10T10:00:00Z</published><updated>2012-02-10T10:00:00Z</updated><content type="html">&lt;p&gt;Vi ho già parlato un po’ di tempo fa di &lt;a href="http://phonegap.com/"&gt;PhoneGap&lt;/a&gt;, un framework sviluppato da Nitobi (società recentemente acquisita da Adobe) con uno scopo decisamente ambizioso: &lt;strong&gt;realizzare applicazione cross – platform in grado di girare su qualunque dispositivo mobile&lt;/strong&gt;. L’approccio è lo stesso utilizzato dalle applicazioni web mobile (HTML + Javascript), ma con una marcia in più: PhoneGap infatti espone tramite una libreria Javascript una serie di funzioni che vanno a interagire direttamente con il device, permettendo di utilizzare funzionalità native (come i servizi di geolocalizzazione, i sensori, ecc.) che altrimenti non sarebbero utilizzabili solamente tramite HTML / JS standard. Queste funzioni sono univoche, ma “sotto il cofano” PhoneGap si preoccupa di mapparle sulle chiamate native della piattaforma specifica: ecco perciò che, ad esempio, per mostrare un alert utilizzeremo sempre la funzione Javascript &lt;strong&gt;&lt;em&gt;navigator.notification.alert, &lt;/em&gt;&lt;/strong&gt;la quale verrà poi declinata da PhoneGap per mostrare la MessageBox di Windows Phone, di iOS o di Android.&lt;/p&gt;  &lt;p&gt;Per questo motivo un progetto PhoneGap non è una generica applicazione web, ma viene creato un progetto specifico per ogni piattaforma, da aprire e manipolare con i tool di sviluppo specifici (Visual Studio per Windows Phone, XCode per iOS e Eclipse per Android).&lt;/p&gt;  &lt;p&gt;E dove sta l’interoperabilità, direte voi? Ogni progetto PhoneGap include una cartella, chiamata&lt;strong&gt; www&lt;/strong&gt;, che include tutti i file necessari della vera e propria applicazione web: è quello il progetto su cui andremo a lavorare, che poi andremo a duplicare per ogni piattaforma (anche se in realtà c’è una soluzione alternativa, di cui vi parlerò più avanti). Questa applicazione web viene poi inclusa all’interno dell’app nativa tramite il controllo browser che è disponibile per ogni piattaforma (ad esempio, WebBrowser in Windows Phone).&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Applicazioni native vs applicazioni cross – platform&lt;/h3&gt;  &lt;p&gt;Il dibattito sull’utilizzo di applicazioni cross – platform rispetto a quelle native è molto acceso tutt’oggi. Ma quali sono i vantaggi e gli svantaggi di questo approccio?&lt;/p&gt;  &lt;h4&gt;I vantaggi&lt;/h4&gt;  &lt;p&gt;Con l’aumentare del numero di piattaforme mobile disponibili sul mercato molte società si sono trovate davanti un problema non indifferente: sviluppare un’applicazione per ogni piattaforma&lt;strong&gt; ha un costo non trascurabile&lt;/strong&gt; e il gioco può non valere la candela, soprattutto nel caso in cui il mobile non sia il core business della società.&lt;/p&gt;  &lt;p&gt;In più, una delle cose che incide maggiormente sui costi è la&lt;strong&gt; difficoltà ad acquisire le conoscenze&lt;/strong&gt; necessaria: HTML e Javascript sono tecnologie molto diffuse e non sono una prerogativa degli sviluppatori, al contrario dei linguaggi nativi come C#, Objective-C e Java.&lt;/p&gt;  &lt;p&gt;Strumenti come PhoneGap permettono di prendere due piccioni con una fava: l’applicazione viene sviluppata una volta sola ed è possibile demandare il compito anche ad uno sviluppatore web, senza necessità di cercare uno sviluppatore mobile ad hoc per ogni piattaforma (e, date le differenze, è molto difficile trovare una persona con piena conoscenza di ognuna di esse).&lt;/p&gt;  &lt;h4&gt;Gli svantaggi&lt;/h4&gt;  &lt;p&gt;Lo svantaggio principale è che &lt;strong&gt;l’interoperabilità in certi casi è una chimera&lt;/strong&gt;, a causa delle grandi differenze nella User Experience proposta da ogni piattaforma: è praticamente impossibile realizzare un’applicazione che offra una user experience e abbia una grafica che si adatti bene ad ogni singola piattaforma. Prendete un’applicazione iPhone e una Windows Phone: le differenze sono numerosissime, a partire dalla grafica, passando per alcuni paradigmi di navigazione (pensiamo al Panorama di Windows Phone).&lt;/p&gt;  &lt;p&gt;In più, non si tratta solo di UX ma anche di sfruttare appieno le funzionalità della piattaforma: pensiamo alle Live Tile, forse la caratteristica più particolare delle applicazioni Windows Phone. Si tratta di una feature che non ha un corrispettivo sulle altre piattaforme: se vogliamo sfruttarla, dovremo perciò scrivere del codice non interoperabile. L’alternativa è quella di non usare questa caratteristica, ma ciò si traduce in un abbassamento della qualità: a parità di funzioni dell’applicazione, l’utente finale ne sceglierà sicuramente una in grado di sfruttare le Live Tile.&lt;/p&gt;  &lt;p&gt;Infine è importante considerare il discorso performance: un’applicazione cross – platform non sarà mai performante quanto un’applicazione nativa. Inoltre, tanto più c’è la necessità di interagire con il device, tanto più soluzioni di questo tipo diventano complesse da realizzare.&lt;/p&gt;  &lt;p&gt;Credo inoltre che, dal punto di vista grafico, Windows Phone sia la piattaforma più difficile: iOS, ad esempio, ha un tipo di interfaccia molto semplice e pulita, facilmente replicabile da un’applicazione web (tanto che con librerie come jQuery Mobile è possibile realizzare applicazioni web mobile praticamente indistinguibili da un’applicazione nativa). Windows Phone ha invece un’interfaccia più particolare e che fa uso di paradigmi come Panorama e Pivot che sono più difficili da ricreare in HTML.&lt;/p&gt;  &lt;p&gt;Il rischio perciò è di realizzare applicazioni con un look &amp;amp; feel lontano dalle guidelines di Metro e quindi in grado di attrarre meno gli utenti rispetto ad un’app nativa, facendo nascere così la necessità di dover sviluppare comunque un’interfaccia diversa per ogni sistema.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;E quindi?&lt;/h3&gt;  &lt;p&gt;Non c’è un vincitore in realtà: tutto dipende dal tipo di applicazione che dovete sviluppare, dalle funzionalità del device che volete sfruttare e dal budget che avete a disposizione. Le applicazioni native hanno e avranno sempre comunque una marcia in più, perlomeno fino a quando HTML e Javascript non saranno supportati nativamente (un po’ come sta avvenendo per le applicazioni Metro style di Windows 8).&lt;/p&gt;  &lt;p&gt;Chiudo questa “introduzione teorica” con &lt;a href="http://blogs.aspitalia.com/cradle/post2730/PhoneGap-Titanium-Esiste-Davvero-Write-Once-Run-Anywhere.aspx"&gt;il link ad un bell’articolo&lt;/a&gt; di Marco De Sanctis di &lt;a href="http://www.aspitalia.com"&gt;ASPItalia&lt;/a&gt;, che traccia un quadro molto preciso della situazione attuale per quanto riguarda lo sviluppo di applicazioni cross platform.&lt;/p&gt;  &lt;h3&gt;PhoneGap e Windows Phone&lt;/h3&gt;  &lt;p&gt;Il matrimonio tra PhoneGap e Windows Phone risale all’uscita di Windows Phone 7.5: questo perchè PhoneGap si appoggia alla tripletta HTML5 / CSS 3 / Javascript, supportata pienamente da Internet Explorer solo a partire dalla versione 9 (vi ricordo che Windows Phone 7 era basato invece su una versione intermedia tra la 7 e la 8).&lt;/p&gt;  &lt;p&gt;La versione 1.3 di PhoneGap (che è anche la release più recente) è stata la prima a supportare pienamente Windows Phone, come potete vedere &lt;a href="http://phonegap.com/about/features"&gt;da questa tabella&lt;/a&gt;: PhoneGap supporta numerosi altri OS mobile (come Symbian o Bada), ma Windows Phone, iOS (a partire dall’iPhone 3GS in poi) e Android sono le uniche 3 piattaforme alle quali è fornito un supporto completo.&lt;/p&gt;  &lt;p&gt;Come già anticipato, tale applicazione viene poi renderizzata attraverso un controllo WebBrowser, il quale è in grado di interagire con il sistema tramite alcune feature messe a disposizione dal controllo (una su tutte, la possibilità di intercettare una funzione Javascript in una pagina e gestirla all’interno dell’applicazione). Se volete approfondire l’argomento, vi consiglio &lt;a href="http://blogs.msdn.com/b/italy/archive/2011/12/15/guest-post-utilizzare-html5-in-applicazioni-native-per-windows-phone.aspx"&gt;questo articolo&lt;/a&gt; del mio amico Ugo pubblicato sul blog di MSDN Italia, dedicato proprio al controllo WebBrowser e alle sue potenzialità.&lt;/p&gt;  &lt;h3&gt;Nel prossimo post&lt;/h3&gt;  &lt;p&gt;Dopo questa introduzione teorica, nel prossimo post inizieremo a vedere come usare concretamente PhoneGap: scaricheremo il pacchetto, lo installeremo e inizieremo a lavorare con Visual Studio per creare una semplice applicazione.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=769" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /><category term="HTML 5" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/HTML+5/default.aspx" /><category term="Android" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Android/default.aspx" /><category term="IOS" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/IOS/default.aspx" /><category term="Javascript" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Javascript/default.aspx" /><category term="PhoneGap" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/PhoneGap/default.aspx" /></entry><entry><title>Nuova versione di SQL CE Toolbox: supporto a VB, log delle query e stringa di connessione read-only</title><link rel="alternate" type="text/html" href="/b/qmatteoq/archive/2012/02/06/nuova_2D00_versione_2D00_di_2D00_sql_2D00_ce_2D00_toolbox_2D00_supporto_2D00_a_2D00_vb_2D00_log_2D00_delle_2D00_query_2D00_e_2D00_stringa_2D00_di_2D00_connessione_2D00_read_2D00_only.aspx" /><id>/b/qmatteoq/archive/2012/02/06/nuova_2D00_versione_2D00_di_2D00_sql_2D00_ce_2D00_toolbox_2D00_supporto_2D00_a_2D00_vb_2D00_log_2D00_delle_2D00_query_2D00_e_2D00_stringa_2D00_di_2D00_connessione_2D00_read_2D00_only.aspx</id><published>2012-02-06T10:00:00Z</published><updated>2012-02-06T10:00:00Z</updated><content type="html">&lt;p&gt;Vi ho già parlato più volte di &lt;a href="http://sqlcetoolbox.codeplex.com/"&gt;SQL CE Toolbox&lt;/a&gt;, sia su questo blog che sulle pagine di ASPItalia: è una utilissima estensione di Visual Studio che vi semplifica la vita quando dovete lavorare con database SQL CE nelle applicazioni Windows Phone.&lt;/p&gt;  &lt;p&gt;E’ di recente uscita la versione 2.6, che aggiunge tre feature molto utili.&lt;/p&gt;  &lt;h3&gt;Supporto a VB.NET&lt;/h3&gt;  &lt;p&gt;Fino ad oggi SQL CE Toolbox era pensato solo per gli sviluppatori C#, in quanto era disponibile la generazione del DataContext e delle varie entità solamente in C#. Con questa nuova versione è disponibile il supporto anche per VB.NET: trovate l’opzione direttamente nella schermata di generazione del DataContext, accessibile dal menu contestuale che compare facendo clic con il tasto destro su un database all’interno del tool.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_2_9.png"&gt;&lt;img title="image" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="image" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/image_thumb_10.png" width="319" height="269" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Log delle query&lt;/h3&gt;  &lt;p&gt;Come saprete se avete letto &lt;a href="http://www.winphoneitalia.com/articoli/windows-phone-7/windows-phone-7.1-database-sqlce.aspx"&gt;il mio articolo introduttivo sull’argomento&lt;/a&gt;, la tecnologia utilizzata da Windows Phone per l’accesso ai dati memorizzati in un database SQL CE è LINQ to SQL, ORM di casa Microsoft passato in secondo piano con l’evoluzione del fratello maggiore Entity Framework ma tornato alla ribalta su Windows Phone, in virtù della maggiore semplicità e leggerezza.&lt;/p&gt;  &lt;p&gt;Utilizzare un ORM, in particolar modo su Windows Phone, significa non scrivere mai query SQL a mano, ma lavorare con gli oggetti, che verranno poi tradotti in righe da inserire nelle varie tabelle del database. A volte, soprattutto in caso di comportamenti anomali o problemi di performance, sarebbe interessante vedere effettivamente il codice SQL generato. Il DataContext generato da LINQ to SQL supporta la proprietà &lt;strong&gt;Log, &lt;/strong&gt;che permette di specificare un output nel quale vogliamo mostrare le query SQL eseguite. Su Windows Phone non è così semplice sfruttare questa feature, dato che non è disponibile una console e i file possono essere salvati solamente nell’Isolated Storage, rendendo complicata l’operazione di estrazione e visualizzazione.&lt;/p&gt;  &lt;p&gt;Il DataContext generato dalla nuova versione di SQL CE Toolbox include un’implementazione della classe TextWriter che va a scrivere il log nella Output Window di Visual Studio nel momento in cui l’applicazione viene eseguita con il debugger collegato. Utilizzarlo è molto semplice: vi basta impostare la proprietà &lt;strong&gt;LogDebug&lt;/strong&gt; del DataContext a &lt;strong&gt;true&lt;/strong&gt;, come nell’esempio:&lt;/p&gt;  &lt;pre class="brush: csharp; ruler: true;"&gt;using (OrdersContext context = new OrdersContext(OrdersContext.ConnectionString))
{
    context.LogDebug = true;
    context.Orders.InsertOnSubmit(order);
    context.SubmitChanges();
}&lt;/pre&gt;

&lt;p&gt;Il risultato sarà, come poteve vedere nello screenshot, che nella &lt;strong&gt;Output Window &lt;/strong&gt;di Visual Studio verrà scrittà la query SQL effettivamente eseguita da LINQ to SQL.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTMLaec17bd.png"&gt;&lt;img title="SNAGHTMLaec17bd" style="border-left-width:0px;border-right-width:0px;background-image:none;border-bottom-width:0px;padding-top:0px;padding-left:0px;display:inline;padding-right:0px;border-top-width:0px;" border="0" alt="SNAGHTMLaec17bd" src="http://qmatteoq.tostring.it/UserFiles/uploaded/qmatteoq/SNAGHTMLaec17bd_thumb.png" width="640" height="451" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;Stringa di connessione read-only&lt;/h3&gt;

&lt;p&gt;Una caratteristica dei database in Windows Phone è il supporto alle connessioni in sola lettura: potete infatti aggiungere un database SQL CE già pronto e popolato (sotto forma di file .sdf) direttamente all’interno del vostro progetto, per poi accedervi dall’applicazione. La stringa di connessione per questo tipo di database è caratterizzata da:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Il prefisso &lt;strong&gt;appdata&lt;/strong&gt;:/&lt;strong&gt; &lt;/strong&gt;come punto di partenza della stringa di connessione (e corrisponde alla root del progetto), mentre per i database memorizzati nello storage viene utilizzato il prefisso &lt;strong&gt;isostore:/&lt;/strong&gt; &lt;/li&gt;

  &lt;li&gt;L’accesso in sola lettura: l’unico modo per inserire dati in un database SQL CE su Windows Phone è mantenerlo nell’Isolated Storage. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Con la versione 2.6 di SQL CE Toolbox il DataContext generato contiene anche una stringa di connessione in modalità read-only per questo tipo di approccio. L’utilizzo è molto semplice, nella vostra applicazione è sufficiente specificare il tipo di connessione in fase di utilizzo del DataContext, come nell’esempio:&lt;/p&gt;

&lt;pre class="brush: csharp; ruler: true;"&gt;//database memorizzato nell&amp;#39;isolated storage
using (OrdersContext context = new OrdersContext(OrdersContext.ConnectionString))
{
    context.Orders.InsertOnSubmit(order);
    context.SubmitChanges();
}

//database aggiunto come file di progetto
using (OrdersContext context = new OrdersContext(OrdersContext.ConnectionStringReadOnly))
{
    context.Orders.InsertOnSubmit(order);
    context.SubmitChanges();
}&lt;/pre&gt;

&lt;h3&gt;Conclusione&lt;/h3&gt;

&lt;p&gt;Potete scaricare SQL CE Toolbox dalla &lt;a href="http://sqlcetoolbox.codeplex.com/releases/view/77137"&gt;pagina ufficiale&lt;/a&gt; su Codeplex: occhio che, essendo un’estensione, è compatibile solamente con le versione a pagamento di Visual Studio.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://dotnetlombardia.org/aggbug.aspx?PostID=766" width="1" height="1"&gt;</content><author><name>qmatteoq</name><uri>http://dotnetlombardia.org/members/qmatteoq/default.aspx</uri></author><category term="Microsoft" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Microsoft/default.aspx" /><category term="Windows Phone" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/Windows+Phone/default.aspx" /><category term="SQL CE" scheme="http://dotnetlombardia.org/b/qmatteoq/archive/tags/SQL+CE/default.aspx" /></entry></feed>