In questa parte parlerò della app capace di interagire con il backend sviluppato nella puntata precedente di questa serie.

Prima di proseguire sento il bisogno di fare un premessa indispensabile. Anche in queste pagine del blog ho parlato di stili di programmazione, pattern, S.O.L.I.D. e via dicendo. Ritengo sia indispensabile seguire per progetti professionali le linee guida e i pattern stranoti che ne assicurano la manutenbilità ed estensibilità.

Nel codice in esposizione, però, tutti questi criteri semplicemente non vengono rispettati. Infatti con coscienza ho pensato di presentare un codice facile da leggere per permettere di comprendere le sfumature dell'SDK in analisi "impipandomene" bellamente delle regole sopracitate per avere un codice almeno lontanamente enterprise-grade.

Per cui l'avvertimento è chiaro: don't do this at home !!! In altri termini quanto presentato funziona perfettamente in ogni sua parte ma per fare una app seria e facilmente manuntenibile occorre modificare la struttura del codice presentato seguendo i sacri testi in circolazione.

OK mi sono lavato la coscienza: possiamo proseguire.

Parto esponendo il modello utilizzato dalla app.

public class FocaccePost
{
  public string Id { get; set; }

  public string NomeUtente { get; set; }

  public string Luogo { get; set; }

  public DateTime DataOra { get; set; }

  public int Voto { get; set; }
}

Analizzando quanto sopra non è possibile non notare che questo difetta di alcun campi presenti all'analogo lato backend: la cosa è perfettamente legale e non provoca alcun errore.

Siccome in questa prima revisione non si propone sincronizzazione offline per ottimizzare le perfomance sono stati inclusi i soli campi indispensabili per il funzionamento.

Oss.: Ogni campo che fa parte del modello della app viene scambiato con il backend sottoforma di stream di oggetti json: escludendone qualcuno, poichè non utilizzato, si rende questo passaggio dei dati più perfomante. Pertanto è sempre buona norma includre nel modello solo i campi realmente utilizzati.

Il modello deve includere quindi ilcampo Id che è la chiave della tabella: per la sincronizzazione on line non è indispensabile proporre altri campi. Nelle prossime parti implementaremo via via altre funzionalità e quindi il modello sopra sarà oggetto di estensione.

Ecco il codice parte client, cioè posto nella app, che permette di interagire con il backend.

public class AzureMobileClient
{
     MobileServiceClient client;
     public AzureMobileClient()
     {
          client = new MobileServiceClient("https://<URL del mobile app service>");
     }

     public async Task<ICollection> ReadAllItemsAsync()
     { 
          try
          {
               //--> On line Sync
               //Rappresenta una tabella temporanea !!
               IMobileServiceTable Focacciatable = client.GetTable();
               return await Focacciatable.ToListAsync();
          }
          catch (Exception e)
          {
               throw;
          }
     }

     public async Task AddUpdateItemAsync(FocaccePost focaccePost)
     {
          IMobileServiceTable Focacciatable = client.GetTable();
          try
          {    
               if (string.IsNullOrEmpty(focaccePost.Id))
               {
                    //e' un inserimento
                    await Focacciatable.InsertAsync(focaccePost);
               }
               else
               {
                    //è una modifica
                    await Focacciatable.UpdateAsync(focaccePost);

               }   
          }

          catch (Exception e)
          {
               throw;
          }
     }
     public async Task DeleteItemAsync(FocaccePost focaccePost)
     {
          try
          {
               IMobileServiceTable Focacciatable = client.GetTable();
               await Focacciatable.DeleteAsync(focaccePost);
          }
          catch (Exception e)
          {
               throw;
          }
     }
}

Rammento che qui ancora non si sta usando l'offline-sync: infatti questa funzionalità sarà implementata nel prossimo. Per tale motivo qualsiasi funzione sopra contatterà direttamente il backend: per tale motivo sarà indispensabile avere una connessione funzionante pena il verificarsi di errori.

Come si vede chiaramente nel codice esposto sopra, delegato a interagire con il backend, in alcun modo si richiamano esplicitamente i metodi del controller: semplicemente in modo naturale con l'ausilio dell'oggetto MobileServiceClient si inoltrano i comandi CRUD (Create, Read, Update e Deleted): questi saranno tradotti per noi in chiamate esplicite ai vari metodi del controller con i corretti parametri.

In altri termini non è necessario richiamare esplicitamente i vari metodi del backend, basta semplicemente utilizzare i metodi dell'oggetto IMobileServiceTable e si inteagirà in modo ottimizzato con i vari metodi del controller.

Per esempio utilizzando ReadAllItemsAsync verrà impegnato il metodo del backend GetAllFocaccePost.

Occorre specificare qualcosa in più su ReadAllItemsAsync: l'oggetto tornato da GetTable è MobileServiceClient: quando interrogato come nel nostro caso usando il metodo ToListAsync restituisce di default 50 tuple.

E' come è possibile farsi restituire il resto ?

Semplicemente lo stesso oggetto permette l'utilizzo dei metodi Take & Skip e l'interrogazione della proprietà IncludeTotalCount: in tal modo diventa molto facile accedere ai dati in modo paginato.

Sempre in tema di interrogazione dei dati è possibile anche farsi restituire un singolo record, usando il metodo LookupAsync, che accetta come parametro, ma guarda un pò, l'id chiave. In tale caso verrà consultato nel controller il metodo GetFocaccePost(string id).

Linkografia

Git Page: Focac-Book in Xamarin