Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1908, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Xamarin, Azure e il Visual Studio Mobile Center - Sincronizzazione offline

Nel post precedente abbiamo visto come sfruttare i servizi di backend di Azure esposti dal Visual Studio Mobile Center per creare una tabella a cui un'app scritta con Xamarin può accedere per memorizzare e recuperare dati.

Nota: il codice sorgente completo sarà fornito nel prossimo post, in cui parlo di autenticazione.

Quell'approccio ha un limite: non memorizza i dati localmente e richiede sempre connettività per poter lavorare. Per fortuna, l'SDK Azure Mobile Client e i servizi di Azure Mobile App offrono anche l'infrastruttura per poter avere dati locali e per sincronizzarli quando online.

(Nota: quanto vedremo in questo post non è legato al Visual Studio Mobile Center, ma è un arricchimento della serie di post).

Per fare questo, l'SDK si avvale di SQLite in locale ed espone il necessario attraverso la classe MobileServiceClient. La cosa bella è che non è necessario installare le apposite librerie di SQLite, perché ci pensa l'SDK a mappare gli oggetti giusti. Quindi, alla solution lasciata in sospeso la volta scorsa aggiungiamo un pacchetto NuGet chiamato Microsoft.Azure.Mobile.Client.SQLiteStore.

Il percorso del db locale
La prima cosa da fare è stabilire il percorso del db locale. Il file system è platform-specific, quindi non sotto lo strato unificato di Xamarin.Forms. Quindi si ricorre al dependency service, dapprima definendo un'interfaccia che stabilisce il contratto (e che creo nella cartella DataAccess della solution):

Fatto questo, vado a definire una classe chiamata DataConnection, che implementa l'interfaccia, su entrambe le piattaforme di mio interesse (Android e iOS perché sono le due ad oggi supportate dal Mobile Center). Ovviamente, su Windows il discorso è analogo.

Android:


iOS:

Ottenuto il percorso del db locale, andremo poi a crearlo e gestirlo.

Utilizzo del db locale
L'accesso al db locale avviene mediante la classe MobileServiceClient, ma il db fisico è rappresentato dalla classe MobileServiceSQLiteStore che va istanziata passando il percorso del file. Una volta istanziata, si invoca il metodo DefineTable<T> tante volte quante sono le tabelle che abbiamo bisogno di generare in locale. Questo metodo crea ma non sovrascrive una tabella. Fatto questo, bisogna inizializzare il meccanismo di sincronizzazione attraverso il metodo SyncContext.InitializeAsync della classe MobileServiceClient, a cui viene passata l'istanza della MobileServiceSQLiteStore e, opzionalmente, un cosiddetto handler che influisca sulla comunicazione. Per esempio, header di autenticazione tramite Web API o informazioni aggiuntive sulla serializzazione JSON.

Altra piccola modifica richiesta è l'utilizzo del metodo GetSyncTable<T> al posto di GetTable. Con GetSyncTable, la libreria sa che deve gestire anche una tabella locale e non solo remota. Poi le operazioni vengono fatte ugualmente con InsertAsync, UpdateAsync, ecc. Solo che il risultato rimane in locale finché non viene invocato PushAsync sul contesto. Questo metodo cercherà di inviare i dati alla tabella remota.

In fase di caricamento dei dati, invece, prima di fare una query o di ottenere un insieme tramite ToListAsync/ToEnumerableAsync, si invoca PullAsync sulla table. Questo metodo effettua una reale sincronizzazione tra remoto e locale e crea una query sulla tabella specificando un nome che serve al sync incrementale. Il nome è libero, in più bisogna passare il risultato di CreateQuery come secondo parametro. Tutto il succo di questo discorso è visibile nel seguente codice e vedrete che i cambiamenti sono davvero pochi, sebbene il codice risulti più lungo per via delle eccezioni da gestire:


Eccezioni e proprietà di sync
Le operazioni di sync possono ovviamente causare eccezioni. I motivi possono essere molto vari, come mancanza di connettività non gestita, differenze tra schema locale e schema remoto (soprattutto se il db remoto è SQL Server), ecc. Le eccezioni che tipicamente andranno gestite sono MobileServicePushFailedException e MobileServiceInvalidOperationException, la prima con la sua proprietà PushResult che contiene un elenco di Errors a rappresentare i vari problemi rilevati. Può anche essere utile conoscere il valore della proprietà PendingOperations, che espone il numero di operazioni in locale che non sono state ancora sincronizzate, per esempio per invocare poi PushAsync. L'ultimissima modifica è l'inizializzazione dello storage per piattaforma. Sia in MainActivity.cs (Android) che in AppDelegate.cs (iOS), prima della chiamata a LoadApplication va aggiunta la seguente riga:

Microsoft.WindowsAzure.MobileServices.CurrentPlatform.Init(); 

Null'altro è richiesto!

L'aver progettato l'app secondo MVVM non rende necessarie modifiche né al ViewModel né alla UI.

Test da fare

Per verificare il meccanismo di sync, provate ad avviare l'app e ad usarla col device disconnesso dalla rete. Poi provate a chiuderla, riconnettere la rete, riavviarla. Ovviamente in scenari reali dovreste prevedere la possibilità di un sync automatico, ad esempio tramite la tecnica del pull-to-refresh sulla ListView.

Questo è tutto. Vi ritroverete un db locale che vi consentirà di lavorare offline e una tabella remota con cui i dati verranno sincronizzati. Nel prossimo post concluderemo parlando di autenticazione.

Alessandro

Print | posted on martedì 14 febbraio 2017 00:00 | Filed Under [ Windows Azure and SQL Azure Xamarin ]

Powered by:
Powered By Subtext Powered By ASP.NET