Abilitare la sincronizzazione offline per l'app per dispositivi mobili Xamarin.FormsEnable offline sync for your Xamarin.Forms mobile app

PanoramicaOverview

Questa esercitazione descrive la funzionalità di sincronizzazione offline di App per dispositivi mobili di Azure per Xamarin.Forms.This tutorial introduces the offline sync feature of Azure Mobile Apps for Xamarin.Forms. La sincronizzazione offline consente agli utenti finali di interagire con un'app, visualizzando, aggiungendo e modificando i dati, anche se non è disponibile una connessione di rete.Offline sync allows end users to interact with a mobile app--viewing, adding, or modifying data--even when there is no network connection. Le modifiche vengono archiviate in un database locale.Changes are stored in a local database. Quando il dispositivo torna online, vengono sincronizzate con il servizio remoto.Once the device is back online, these changes are synced with the remote service.

Questa esercitazione si basa sulla soluzione di avvio rapido per Xamarin.Forms per le app per dispositivi mobili create quando si completa l'esercitazione [Creare un'app per Xamarin.iOS].This tutorial is based on the Xamarin.Forms quickstart solution for Mobile Apps that you create when you complete the tutorial [Create a Xamarin iOS app]. La soluzione di avvio rapido per Xamarin.Forms contiene il codice per supportare la sincronizzazione offline, che deve solo essere abilitata.The quickstart solution for Xamarin.Forms contains the code to support offline sync, which just needs to be enabled. In questa esercitazione viene aggiornata la soluzione di avvio rapido per attivare le funzionalità offline delle app per dispositivi mobili.In this tutorial, you update the quickstart solution to turn on the offline features of Azure Mobile Apps. Viene anche evidenziato il codice specifico per le funzionalità offline nell'app.We also highlight the offline-specific code in the app. Se non si usa la soluzione di avvio rapido scaricata, è necessario aggiungere al progetto il pacchetto di estensione per l'accesso ai dati.If you do not use the downloaded quickstart solution, you must add the data access extension packages to your project. Per altre informazioni sui pacchetti di estensione server, vedere l'articolo Usare l'SDK del server back-end .NET per App per dispositivi mobili di Azure.For more information about server extension packages, see Work with the .NET backend server SDK for Azure Mobile Apps.

Per altre informazioni sulla funzionalità di sincronizzazione offline, vedere l'argomento Sincronizzazione di dati offline nelle app per dispositivi mobili di Azure.To learn more about the offline sync feature, see the topic Offline Data Sync in Azure Mobile Apps.

Abilitare la funzionalità di sincronizzazione offline nella soluzione di avvio rapidoEnable offline sync functionality in the quickstart solution

Il codice per la sincronizzazione offline viene incluso nel progetto usando le direttive del preprocessore C#.The offline sync code is included in the project by using C# preprocessor directives. Quando il simbolo OFFLINE_SYNC_ENABLED viene definito, questi percorsi di codice vengono inclusi nella build.When the OFFLINE_SYNC_ENABLED symbol is defined, these code paths are included in the build. Per le app di Windows, è anche necessario installare la piattaforma SQLite.For Windows apps, you must also install the SQLite platform.

  1. In Visual Studio fare clic con il pulsante destro del mouse sulla soluzione > Gestisci pacchetti NuGet per la soluzione, quindi cercare e installare il pacchetto NuGet Microsoft.Azure.Mobile.Client.SQLiteStore per tutti i progetti della soluzione.In Visual Studio, right-click the solution > Manage NuGet Packages for Solution..., then search for and install the Microsoft.Azure.Mobile.Client.SQLiteStore NuGet package for all projects in the solution.
  2. In Esplora soluzioni aprire il file TodoItemManager.cs dal progetto con portabile nel nome, ovvero il progetto Libreria di classi portabile, quindi rimuovere il commento dalla direttiva del preprocessore seguente:In the Solution Explorer, open the TodoItemManager.cs file from the project with Portable in the name, which is Portable Class Library project, then uncomment the following preprocessor directive:

     #define OFFLINE_SYNC_ENABLED
    
  3. (Facoltativo) Per supportare i dispositivi Windows, installare uno dei pacchetti di runtime SQLite seguenti:(Optional) To support Windows devices, install one of the following SQLite runtime packages:

  4. (Facoltativo) In ogni progetto app Windows fare clic con il pulsante destro del mouse su Riferimenti > Aggiungi riferimento, espandere la cartella Windows > Estensioni.(Optional) In each Windows app project, right-click References > Add Reference..., expand the Windows folder > Extensions. Abilitare SQLite for Windows SDK appropriato insieme a Visual C++ 2013 Runtime for Windows SDK.Enable the appropriate SQLite for Windows SDK along with the Visual C++ 2013 Runtime for Windows SDK. I nomi degli SDK di SQLite sono leggermente diversi per ogni piattaforma Windows.The SQLite SDK names vary slightly with each Windows platform.

Verificare il codice di sincronizzazione del clientReview the client sync code

Ecco un breve riepilogo degli elementi già inclusi nel codice dell'esercitazione nelle direttive #if OFFLINE_SYNC_ENABLED .Here is a brief overview of what is already included in the tutorial code inside the #if OFFLINE_SYNC_ENABLED directives. La funzionalità di sincronizzazione offline è nel file di progetto TodoItemManager.cs nel progetto Libreria di classi portabile.The offline sync functionality is in the TodoItemManager.cs project file in the Portable Class Library project. Per una panoramica concettuale della funzionalità, vedere Sincronizzazione di dati offline nelle app per dispositivi mobili di Azure.For a conceptual overview of the feature, see Offline Data Sync in Azure Mobile Apps.

  • Prima di poter eseguire qualsiasi operazione su tabella, è necessario inizializzare l'archivio locale.Before any table operations can be performed, the local store must be initialized. Il database di archiviazione locale viene inizializzato nel costruttore della classe TodoItemManager usando il codice seguente:The local store database is initialized in the TodoItemManager class constructor by using the following code:

      var store = new MobileServiceSQLiteStore(OfflineDbPath);
      store.DefineTable<TodoItem>();
    
      //Initializes the SyncContext using the default IMobileServiceSyncHandler.
      this.client.SyncContext.InitializeAsync(store);
    
      this.todoTable = client.GetSyncTable<TodoItem>();
    

    Questo crea un nuovo database SQL locale usando la classe MobileServiceSQLiteStore.This code creates a new local SQLite database using the MobileServiceSQLiteStore class.

    Il metodo DefineTable crea nell'archivio locale una tabella corrispondente ai campi del tipo specificato.The DefineTable method creates a table in the local store that matches the fields in the provided type. Il tipo non deve necessariamente includere tutte le colonne presenti nel database remoto.The type doesn't have to include all the columns that are in the remote database. È possibile archiviare un subset di colonne.It is possible to store a subset of columns.

  • Il campo todoTable in TodoItemManager è un tipo IMobileServiceSyncTable invece di IMobileServiceTable.The todoTable field in TodoItemManager is an IMobileServiceSyncTable type instead of IMobileServiceTable. Questa classe usa il database locale per tutte le operazioni di creazione, lettura, aggiornamento ed eliminazione (CRUD, Create, Read, Update, Delete) sulle tabelle.This class uses the local database for all create, read, update, and delete (CRUD) table operations. È possibile decidere quando effettuare il push delle modifiche nel back-end dell'app per dispositivi mobili chiamando PushAsync in IMobileServiceSyncContext.You decide when those changes are pushed to the Mobile App backend by calling PushAsync on the IMobileServiceSyncContext. Questo contesto di sincronizzazione aiuta a mantenere le relazioni tra tabelle rilevando le modifiche apportate da un'app client in tutte le tabelle ed effettuandone il push quando viene chiamato PushAsync.The sync context helps preserve table relationships by tracking and pushing changes in all tables a client app has modified when PushAsync is called.

    Il metodo SyncAsync seguente viene chiamato per la sincronizzazione con il back-end dell'app per dispositivi mobili:The following SyncAsync method is called to sync with the Mobile App backend:

      public async Task SyncAsync()
      {
          ReadOnlyCollection<MobileServiceTableOperationError> syncErrors = null;
    
          try
          {
              await this.client.SyncContext.PushAsync();
    
              await this.todoTable.PullAsync(
                  "allTodoItems",
                  this.todoTable.CreateQuery());
          }
          catch (MobileServicePushFailedException exc)
          {
              if (exc.PushResult != null)
              {
                  syncErrors = exc.PushResult.Errors;
              }
          }
    
          // Simple error/conflict handling.
          if (syncErrors != null)
          {
              foreach (var error in syncErrors)
              {
                  if (error.OperationKind == MobileServiceTableOperationKind.Update && error.Result != null)
                  {
                      //Update failed, reverting to server's copy.
                      await error.CancelAndUpdateItemAsync(error.Result);
                  }
                  else
                  {
                      // Discard local change.
                      await error.CancelAndDiscardItemAsync();
                  }
    
                  Debug.WriteLine(@"Error executing sync operation. Item: {0} ({1}). Operation discarded.",
                      error.TableName, error.Item["id"]);
              }
          }
      }
    

    Questo esempio usa la gestione degli errori semplice con il gestore di sincronizzazione predefinito.This sample uses simple error handling with the default sync handler. Una vera applicazione gestirà i diversi errori come condizioni di rete, conflitti del server e altro usando un'implementazione IMobileServiceSyncHandler personalizzata.A real application would handle the various errors like network conditions and server conflicts by using a custom IMobileServiceSyncHandler implementation.

Considerazioni sulla sincronizzazione offlineOffline sync considerations

Nell'esempio il metodo SyncAsync viene chiamato solo all'avvio e quando viene richiesta una sincronizzazione in modo specifico.In the sample, the SyncAsync method is only called on start-up and when a sync is requested. Per avviare la sincronizzazione in un'app Android o iOS, trascinare verso il basso nell'elenco di elementi. Per Windows, usare il pulsante Sincronizza.To initiate a sync in an Android or iOS app, pull down on the items list; for Windows, use the Sync button. In un'applicazione effettiva è anche possibile attivare la sincronizzazione in caso di cambiamento dello stato della rete.In a real-world application, you could also make the sync trigger when the network state changes.

Quando viene effettuato il pull in una tabella con aggiornamenti locali in sospeso rilevati dal contesto, tale operazione attiva automaticamente un'operazione push nel contesto precedente.When a pull is executed against a table that has pending local updates tracked by the context, that pull operation automatically triggers a preceding context push. Quando si aggiornano, aggiungono e completano elementi in questo esempio, è possibile omettere la chiamata PushAsync esplicita.When refreshing, adding, and completing items in this sample, you can omit the explicit PushAsync call.

Nel codice fornito viene eseguita una query su tutti i record presenti nella tabella TodoItem remota, ma è anche possibile filtrare i record passando un ID di query e una query a PushAsync.In the provided code, all records in the remote TodoItem table are queried, but it is also possible to filter records by passing a query id and query to PushAsync. Per altre informazioni, vedere la sezione Sincronizzazione incrementale in Sincronizzazione di dati offline nelle app per dispositivi mobili di Azure.For more information, see the section Incremental Sync in Offline Data Sync in Azure Mobile Apps.

Eseguire l'app clientRun the client app

Con la sincronizzazione offline abilitata, è possibile eseguire l'applicazione client almeno una volta in ogni piattaforma per popolare il database di archiviazione locale.With offline sync now enabled, run the client application at least once on each platform to populate the local store database. Più avanti viene simulato uno scenario offline e vengono modificati i dati nell'archivio locale mentre l'app è offline.Later, simulate an offline scenario and modify the data in the local store while the app is offline.

Aggiornare il comportamento di sincronizzazione dell'app clientUpdate the sync behavior of the client app

In questa sezione viene modificato il progetto client per simulare uno scenario offline usando un URL di applicazione non valido per il back-end.In this section, modify the client project to simulate an offline scenario by using an invalid application URL for your backend. In alternativa, è possibile disattivare le connessioni di rete attivando la "Modalità aereo" nel dispositivo.Alternatively, you can turn off network connections by moving your device to "Airplane mode." Quando si aggiungono o si modificano elementi di dati, queste modifiche vengono conservate nell'archivio locale, ma non vengono sincronizzate con l'archivio dati back-end fino a quando non viene ristabilita la connessione.When you add or change data items, these changes are held in the local store, but not synced to the backend data store until the connection is re-established.

  1. In Esplora soluzioni aprire il file di progetto Constants.cs dal progetto Portatile e modificare il valore di ApplicationURL in modo che punti a un URL non valido:In the Solution Explorer, open the Constants.cs project file from the Portable project and change the value of ApplicationURL to point to an invalid URL:

     public static string ApplicationURL = @"https://your-service.azurewebsites.net/";
    
  2. Aprire il file TodoItemManager.cs dal progetto Portable, quindi aggiungere un blocco catch aggiuntivo per la classe Exception di base al blocco try...catch in SyncAsync.Open the TodoItemManager.cs file from the Portable project, then add a catch for the base Exception class to the try...catch block in SyncAsync. Questo blocco catch scrive il messaggio dell'eccezione nella console, come segue:This catch block writes the exception message to the console, as follows:

         catch (Exception ex)
         {
             Console.Error.WriteLine(@"Exception: {0}", ex.Message);
         }
    
  3. Compilare ed eseguire l'app client.Build and run the client app. Aggiungere nuovi elementi.Add some new items. Si noti che un'eccezione viene registrata nella console per ogni tentativo di sincronizzazione con il back-end.Notice that an exception is logged in the console for each attempt to sync with the backend. I nuovi elementi sono presenti solo nell'archivio locale finché non è possibile effettuarne il push al back-end mobile.These new items exist only in the local store until they can be pushed to the mobile backend. L'app client si comporta come se fosse connessa al back-end, supportando tutte le operazioni CRUD (creazione, lettura, aggiornamento ed eliminazione).The client app behaves as if it is connected to the backend, supporting all create, read, update, delete (CRUD) operations.
  4. Chiudere l'app e riavviarla per verificare che i nuovi elementi creati siano salvati in modo permanente nell'archivio locale.Close the app and restart it to verify that the new items you created are persisted to the local store.
  5. (Facoltativo) Usare Visual Studio per visualizzare la tabella di database SQL di Azure per verificare che i dati nel database back-end non siano cambiati.(Optional) Use Visual Studio to view your Azure SQL Database table to see that the data in the backend database has not changed.

    In Visual Studio aprire Esplora server.In Visual Studio, open Server Explorer. Passare al database in Azure->Database SQL.Navigate to your database in Azure->SQL Databases. Fare clic con il pulsante destro del mouse sul database e scegliere Apri in Esplora oggetti di SQL Server.Right-click your database and select Open in SQL Server Object Explorer. È ora possibile passare alla tabella di database SQL e al relativo contenuto.Now you can browse to your SQL database table and its contents.

Aggiornare l'app client per la riconnessione al back-end mobileUpdate the client app to reconnect your mobile backend

In questa sezione viene riconnessa l'app al back-end mobile, azione che consente di simulare il ritorno dell'app nello stato online.In this section, reconnect the app to the mobile backend, which simulates the app coming back to an online state. Quando si esegue il movimento di aggiornamento, i dati vengono sincronizzati con il back-end mobile.When you perform the refresh gesture, data is synced to your mobile backend.

  1. Riaprire il file Constants.cs.Reopen Constants.cs. Correggere il valore applicationURL in modo che faccia riferimento all'URL corretto.Correct the applicationURL to point to the correct URL.
  2. Ricompilare ed eseguire l'app client.Rebuild and run the client app. L'app prova a eseguire la sincronizzazione con il back-end dell'app per dispositivi mobili dopo l'avvio.The app attempts to sync with the mobile app backend after launching. Verificare che non vengano registrate eccezioni nella console di debug.Verify that no exceptions are logged in the debug console.
  3. (Facoltativo) Visualizzare i dati aggiornati usando Esplora oggetti di SQL Server o uno strumento REST come Fiddler o Postman.(Optional) View the updated data using either SQL Server Object Explorer or a REST tool like Fiddler or Postman. Si noti che i dati sono stati sincronizzati tra il database di back-end e l'archivio locale.Notice the data has been synchronized between the backend database and the local store.

    Si noti che i dati sono stati sincronizzati tra il database e l'archivio locale e includono gli elementi aggiunti mentre l'app era disconnessa.Notice the data has been synchronized between the database and the local store and contains the items you added while your app was disconnected.

Risorse aggiuntiveAdditional Resources