Habilitación de la sincronización sin conexión para la aplicación móvil Xamarin.FormsEnable offline sync for your Xamarin.Forms mobile app

Nota

Visual Studio App Center está invirtiendo en servicios nuevos e integrados que son fundamentales para el desarrollo de aplicaciones móviles.Visual Studio App Center is investing in new and integrated services central to mobile app development. Los desarrolladores pueden usar los servicios de compilación, prueba y distribución para configurar la canalización de entrega e integración continuas.Developers can use Build, Test and Distribute services to set up Continuous Integration and Delivery pipeline. Una vez que se ha implementado la aplicación, los desarrolladores pueden supervisar el estado y el uso de su aplicación con los servicios de análisis y diagnóstico, e interactuar con los usuarios mediante el servicio de inserción.Once the app is deployed, developers can monitor the status and usage of their app using the Analytics and Diagnostics services, and engage with users using the Push service. Además, los desarrolladores pueden aprovechar Auth para autenticar a los usuarios y el servicio de datos para almacenar y sincronizar los datos de la aplicación en la nube.Developers can also leverage Auth to authenticate their users and Data service to persist and sync app data in the cloud. Consulte App Center hoy mismo.Check out App Center today.

Información generalOverview

Este tutorial presenta la característica de sincronización sin conexión de Azure Mobile Apps para Xamarin.Forms.This tutorial introduces the offline sync feature of Azure Mobile Apps for Xamarin.Forms. La sincronización sin conexión permite a los usuarios finales interactuar con una aplicación móvil (ver, agregar o modificar datos), incluso cuando no hay ninguna conexión de red.Offline sync allows end users to interact with a mobile app--viewing, adding, or modifying data--even when there is no network connection. Los cambios se almacenan en una base de datos local.Changes are stored in a local database. Una vez que el dispositivo se vuelve a conectar, estos cambios se sincronizan con el servicio remoto.Once the device is back online, these changes are synced with the remote service.

Este tutorial se basa en la solución de inicio rápido de Xamarin.Forms para Mobile Apps que crea al completar el tutorial [Crear una aplicación 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 solución de inicio rápido para Xamarin.Forms contiene el código para admitir la sincronización sin conexión, que solo debe habilitarse.The quickstart solution for Xamarin.Forms contains the code to support offline sync, which just needs to be enabled. En este tutorial, actualizará la solución de inicio rápido para activar las características sin conexión de Azure Mobile Apps.In this tutorial, you update the quickstart solution to turn on the offline features of Azure Mobile Apps. También nos centraremos en el código sin conexión específico de la aplicación.We also highlight the offline-specific code in the app. Si no usa la solución de inicio rápido descargada, debe agregar paquetes de extensión de acceso de datos al proyecto.If you do not use the downloaded quickstart solution, you must add the data access extension packages to your project. Para obtener más información acerca de los paquetes de extensión de servidor, consulte Trabajar con el SDK del servidor back-end de .NET para Aplicaciones móviles de Azure.For more information about server extension packages, see Work with the .NET backend server SDK for Azure Mobile Apps.

Para obtener más información acerca de la característica de sincronización sin conexión, consulte el tema Sincronización de datos sin conexión en Aplicaciones móviles de Azure.To learn more about the offline sync feature, see the topic Offline Data Sync in Azure Mobile Apps.

Habilitación de la funcionalidad de sincronización sin conexión en la solución de inicio rápidoEnable offline sync functionality in the quickstart solution

Se incluye el código de sincronización sin conexión en el proyecto mediante el uso de directivas de preprocesador de C#.The offline sync code is included in the project by using C# preprocessor directives. Cuando se define el símbolo OFFLINE_SYNC_ENABLED, se incluyen en la compilación estas rutas de acceso del código.When the OFFLINE_SYNC_ENABLED symbol is defined, these code paths are included in the build. Para las aplicaciones de Windows, también debe instalar la plataforma de SQLite.For Windows apps, you must also install the SQLite platform.

  1. En Visual Studio, haga clic con el botón derecho en la solución > Administrar paquetes NuGet para la solución... y, después, busque e instale el paquete NuGet Microsoft.Azure.Mobile.Client.SQLiteStore en todos los proyectos de la solución.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. En el Explorador de soluciones, abra el archivo TodoItemManager.cs desde el proyecto con Portable en el nombre, que es el proyecto de biblioteca de clases portable, y, después, quite la directiva de preprocesador siguiente: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. (Opcional) Para admitir dispositivos de Windows, instale uno de los siguientes paquetes en el sistema de tiempo de ejecución de SQLite:(Optional) To support Windows devices, install one of the following SQLite runtime packages:

  4. (Opcional) En cada proyecto de aplicación de Windows, haga clic con el botón derecho en Referencias > Agregar referencia... , amplíe la carpeta Windows > Extensiones.(Optional) In each Windows app project, right-click References > Add Reference..., expand the Windows folder > Extensions. Habilite el SDK de SQLite para Windows junto con el SDK Visual C++ 2013 Runtime para Windows.Enable the appropriate SQLite for Windows SDK along with the Visual C++ 2013 Runtime for Windows SDK. Los nombres de SDK de SQLite varían ligeramente con cada plataforma de Windows.The SQLite SDK names vary slightly with each Windows platform.

Revisión del código de sincronización de clienteReview the client sync code

Esta es una breve descripción de lo que ya está incluido en el código del tutorial dentro de las directivas #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 funcionalidad de sincronización sin conexión está en el archivo de proyecto TodoItemManager.cs en el proyecto de biblioteca de clases portable.The offline sync functionality is in the TodoItemManager.cs project file in the Portable Class Library project. Para obtener información general conceptual de la característica, consulte Sincronización de datos sin conexión en Aplicaciones móviles de Azure.For a conceptual overview of the feature, see Offline Data Sync in Azure Mobile Apps.

  • Antes de poder realizar cualquier operación de tabla, se debe inicializar el almacén local.Before any table operations can be performed, the local store must be initialized. La base de datos del almacén local se inicializa en el constructor de clase TodoItemManager con el código siguiente: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>();
    

    Este código crea una nueva SQLite local con la clase MobileServiceSQLiteStore.This code creates a new local SQLite database using the MobileServiceSQLiteStore class.

    El método DefineTable crea una tabla en el almacén local que coincide con los campos del tipo proporcionado.The DefineTable method creates a table in the local store that matches the fields in the provided type. El tipo no tiene que incluir todas las columnas que se encuentran en la base de datos remota.The type doesn't have to include all the columns that are in the remote database. Es posible almacenar solo un subconjunto de columnas.It is possible to store a subset of columns.

  • El campo todoTable de TodoItemManager es un tipo IMobileServiceSyncTable en lugar de IMobileServiceTable.The todoTable field in TodoItemManager is an IMobileServiceSyncTable type instead of IMobileServiceTable. Esta clase usa la base de datos local para todas las operaciones de creación, lectura, actualización y eliminación (CRUD) de tablas.This class uses the local database for all create, read, update, and delete (CRUD) table operations. Para decidir cuándo se deben integrar esos cambios en el back-end de aplicación móvil, llame a PushAsync en el método IMobileServiceSyncContext.You decide when those changes are pushed to the Mobile App backend by calling PushAsync on the IMobileServiceSyncContext. El contexto de sincronización ayuda a mantener las relaciones entre tablas mediante el seguimiento y la inserción de los cambios en todas las tablas modificadas por una aplicación cliente cuando se llama a 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.

    El siguiente método SyncAsync se llama para realizar la sincronización con el back-end de aplicación móvil: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"]);
              }
          }
      }
    

    Este ejemplo utiliza un control de errores sencillo con el controlador de sincronización predeterminado.This sample uses simple error handling with the default sync handler. Una aplicación real controlaría los diversos errores como condiciones de red y conflictos de red mediante el uso de una implementación personalizada de IMobileServiceSyncHandler .A real application would handle the various errors like network conditions and server conflicts by using a custom IMobileServiceSyncHandler implementation.

Consideraciones sobre la sincronización sin conexiónOffline sync considerations

En el ejemplo, solo se llama al método SyncAsync al inicio y cuando se solicita una sincronización.In the sample, the SyncAsync method is only called on start-up and when a sync is requested. Para iniciar la sincronización en una aplicación Android o iOS, despliegue la lista de elementos; para Windows, utilice el botón Sincronizar .To initiate a sync in an Android or iOS app, pull down on the items list; for Windows, use the Sync button. En una aplicación real, también puede hacer que la sincronización se desencadene cuando cambia el estado de la red.In a real-world application, you could also make the sync trigger when the network state changes.

Si se ejecuta una extracción en una tabla que tiene actualizaciones locales pendientes seguidas por el contexto, la operación de extracción desencadenará de forma automática una inserción de contexto anterior.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. Al actualizar, agregar y completar elementos en este ejemplo, se puede omitir la llamada explícita a PushAsync.When refreshing, adding, and completing items in this sample, you can omit the explicit PushAsync call.

En el ejemplo proporcionado, se consultan todos los registros de la tabla TodoItem remota, pero también es posible filtrar registros pasando un identificador de consulta y una consulta 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. Para más información, consulte la sección Sincronización incremental en Sincronización de datos sin conexión en Aplicaciones móviles de Azure.For more information, see the section Incremental Sync in Offline Data Sync in Azure Mobile Apps.

Ejecución de la aplicación clienteRun the client app

Con la sincronización sin conexión habilitada, ejecute la aplicación cliente al menos una vez en cada plataforma para rellenar la base de datos del almacén local.With offline sync now enabled, run the client application at least once on each platform to populate the local store database. Después, simulará un escenario sin conexión y modificará los datos del almacén local mientras la aplicación está sin conexión.Later, simulate an offline scenario and modify the data in the local store while the app is offline.

Actualización del comportamiento de sincronización de la aplicación clienteUpdate the sync behavior of the client app

En esta sección, modificará el proyecto de cliente para simular un escenario sin conexión usando una dirección URL de aplicación no válida para el back-end.In this section, modify the client project to simulate an offline scenario by using an invalid application URL for your backend. Como alternativa, puede desactivar las conexiones de red cambiando el dispositivo a "Modo de avión".Alternatively, you can turn off network connections by moving your device to "Airplane mode." Al agregar o cambiar elementos de datos, estos cambios se conservan en el almacén local, pero no se sincronizan con el almacén de datos de back-end hasta que se restablezca la conexión.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. En el Explorador de soluciones, abra el archivo de proyecto Constants.cs desde el proyecto Portable y cambie el valor de ApplicationURL para que apunte a una dirección URL no válida: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. Abra el archivo TodoItemManager.cs desde el proyecto Portable, agregue después un valor catch adicional para la clase Exception de base al bloque try...catch de 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. Este bloque catch escribe el mensaje de excepción en la consola, de la forma siguiente:This catch block writes the exception message to the console, as follows:

         catch (Exception ex)
         {
             Console.Error.WriteLine(@"Exception: {0}", ex.Message);
         }
    
  3. Compile y ejecute la aplicación cliente.Build and run the client app. Agregue nuevos elementos.Add some new items. Tenga en cuenta que la excepción se registra en la consola para cada intento de sincronización con el back-end.Notice that an exception is logged in the console for each attempt to sync with the backend. Estos nuevos elementos solo existirán en el almacén local hasta que se puedan insertar en el back-end móvil.These new items exist only in the local store until they can be pushed to the mobile backend. La aplicación cliente se comporta como si estuviera conectada al back-end y admite todas las operaciones de creación, lectura, actualización y eliminación (CRUD).The client app behaves as if it is connected to the backend, supporting all create, read, update, delete (CRUD) operations.

  4. Cierre la aplicación y reiníciela para comprobar que los nuevos elementos que creó se mantienen en el almacén local.Close the app and restart it to verify that the new items you created are persisted to the local store.

  5. (Opcional) Use Visual Studio para ver la tabla de su base de datos de Azure SQL y observe que los datos de la base de datos de back-end no han cambiado.(Optional) Use Visual Studio to view your Azure SQL Database table to see that the data in the backend database has not changed.

    En Visual Studio, abra el Explorador de servidores.In Visual Studio, open Server Explorer. Vaya a la base de datos en Azure->SQL Databases.Navigate to your database in Azure->SQL Databases. Haga clic con el botón derecho en la base de datos y seleccione Abrir en el Explorador de objetos de SQL Server.Right-click your database and select Open in SQL Server Object Explorer. Ahora puede buscar la tabla de base de datos SQL y su contenido.Now you can browse to your SQL database table and its contents.

Actualización de la aplicación cliente para volver a conectar el back-end móvilUpdate the client app to reconnect your mobile backend

En esta sección se volverá a conectar la aplicación al back-end móvil, que simula que la aplicación vuelve a un estado en línea.In this section, reconnect the app to the mobile backend, which simulates the app coming back to an online state. Al realizar el gesto de la actualización, los datos se sincronizarán con el back-end móvil.When you perform the refresh gesture, data is synced to your mobile backend.

  1. Vuelva a abrir Constants.cs.Reopen Constants.cs. Corrija applicationURL para que apunte a la dirección URL correcta.Correct the applicationURL to point to the correct URL.

  2. Vuelva a compilar la aplicación cliente y ejecútela.Rebuild and run the client app. La aplicación intenta sincronizarse con el back-end de aplicación móvil después de iniciarse.The app attempts to sync with the mobile app backend after launching. Compruebe que no hay excepciones registradas en la consola de depuración.Verify that no exceptions are logged in the debug console.

  3. (Opcional) Consulte los datos actualizados mediante el Explorador de objetos de SQL Server o una herramienta REST como Fiddler o Postman.(Optional) View the updated data using either SQL Server Object Explorer or a REST tool like Fiddler or Postman. Observe que los datos se han sincronizado entre la base de datos back-end y el almacén local.Notice the data has been synchronized between the backend database and the local store.

    Observe que los datos se han sincronizado entre la base de datos y el almacén local, y contienen los elementos que agregó mientras la aplicación estaba desconectada.Notice the data has been synchronized between the database and the local store and contains the items you added while your app was disconnected.

Recursos adicionalesAdditional Resources