为 Xamarin.iOS 移动应用启用脱机同步Enable offline sync for your Xamarin.iOS mobile app


本教程介绍适用于 Xamarin.iOS 的 Azure 移动应用的脱机同步功能。This tutorial introduces the offline sync feature of Azure Mobile Apps for Xamarin.iOS. 脱机同步允许最终用户与移动应用交互(查看、添加或修改数据),即使在没有网络连接时也是如此。Offline sync allows end users to interact with a mobile app--viewing, adding, or modifying data--even when there is no network connection. 在本地数据库中存储更改。Changes are stored in a local database. 设备重新联机后,这些更改会与远程服务同步。Once the device is back online, these changes are synced with the remote service.

本教程更新 创建 Xamarin iOS 应用 中的 Xamarin.iOS 应用项目,以支持 Azure 移动应用的脱机功能。In this tutorial, update the Xamarin.iOS app project from Create a Xamarin iOS app to support the offline features of Azure Mobile Apps. 如果不使用下载的快速入门服务器项目,必须将数据访问扩展包添加到项目。If you do not use the downloaded quick start server project, you must add the data access extension packages to your project. 有关服务器扩展包的详细信息,请参阅 Work with the .NET backend server SDK for Azure Mobile Apps(使用适用于 Azure 移动应用的 .NET 后端服务器 SDK)。For more information about server extension packages, see Work with the .NET backend server SDK for Azure Mobile Apps.

若要了解有关脱机同步功能的详细信息,请参阅 Azure 移动应用中的脱机数据同步 主题。To learn more about the offline sync feature, see the topic Offline Data Sync in Azure Mobile Apps.

更新客户端应用以支持脱机功能Update the client app to support offline features

脱机情况下,可使用 Azure 移动应用脱机功能与本地数据库交互。Azure Mobile App offline features allow you to interact with a local database when you are in an offline scenario. 要在应用中使用这些功能,请将 SyncContext 初始化到本地存储。To use these features in your app, initialize a SyncContext to a local store. 通过 [IMobileServiceSyncTable] 接口引用表。Reference your table through the [IMobileServiceSyncTable] interface. SQLite 在设备上用作本地存储。SQLite is used as the local store on the device.

  1. 打开在创建 Xamarin iOS 应用教程中完成的项目中的 NuGet 包管理器,然后搜索并安装 Microsoft.Azure.Mobile.Client.SQLiteStore NuGet 包 。Open the NuGet package manager in the project that you completed in the Create a Xamarin iOS app tutorial, then search for and install the Microsoft.Azure.Mobile.Client.SQLiteStore NuGet package.
  2. 打开 QSTodoService.cs 文件,并取消注释 #define OFFLINE_SYNC_ENABLED 定义。Open the QSTodoService.cs file and uncomment the #define OFFLINE_SYNC_ENABLED definition.
  3. 重新生成并运行客户端应用。Rebuild and run the client app. 应用的工作方式与启用脱机同步之前一样。但是,本地数据库中现在填充了可以在脱机方案中使用的数据。The app works the same as it did before you enabled offline sync. However, the local database is now populated with data that can be used in an offline scenario.

更新应用以与后端断开连接Update the app to disconnect from the backend

本部分断开与移动应用后端的连接,以模拟脱机情况。In this section, you break the connection to your Mobile App backend to simulate an offline situation. 添加数据项时,异常处理程序会指示该应用处于脱机模式。When you add data items, your exception handler tells you that the app is in offline mode. 在此状态下,新项会添加到本地存储,下次以连接状态运行推送时,这些新项将同步到移动应用后端。In this state, new items added in the local store and will be synced to the mobile app backend when push is next run in a connected state.

  1. 在共享项目中编辑 QSToDoService.cs。Edit QSToDoService.cs in the shared project. applicationURL 更改为指向无效的 URL:Change the applicationURL to point to an invalid URL:

      const string applicationURL = @"https://your-service.chinacloudsites.fail";

    还可以通过在设备上禁用 wifi 和手机网络或使用飞行模式来演示脱机行为。You can also demonstrate offline behavior by disabling wifi and cellular networks on the device or using airplane mode.

  2. 构建并运行应用程序。Build and run the app. 请注意,在应用启动时,同步刷新将失败。Notice your sync failed on refresh when the app launched.

  3. 输入新项,并注意每次单击“保存”时,推送将失败,并显示 [CancelledByNetworkError] 状态 。Enter new items and notice that push fails with a [CancelledByNetworkError] status each time you click Save. 但是,新的待办事项在可被推送到移动应用后端之前,将存在于本地存储中。However, the new todo items exist in the local store until they can be pushed to the mobile app backend. 在生产应用中,如果取消显示这些异常,客户端应用的行为将会像它仍连接到移动应用后端时一样。In a production app, if you suppress these exceptions the client app behaves as if it's still connected to the mobile app backend.

  4. 关闭应用程序并重新启动它,以验证你创建的新项目是否已永久保存到本地存储中。Close the app and restart it to verify that the new items you created are persisted to the local store.

  5. (可选)如果电脑上装有 Visual Studio,打开“服务器资源管理器” 。(Optional) If you have Visual Studio installed on a PC, open Server Explorer. 导航到“Azure” -> “SQL 数据库” 中的数据库。Navigate to your database in Azure-> SQL Databases. 右键单击数据库并选择“在 SQL Server 对象资源管理器中打开” 。Right-click your database and select Open in SQL Server Object Explorer. 现在便可以浏览 SQL 数据库表及其内容。Now you can browse to your SQL database table and its contents. 验证确认后端数据库中的数据未更改。Verify that the data in the backend database has not changed.

  6. (可选)通过 Fiddler 或 Postman 之类的 REST 工具使用 https://<your-mobile-app-backend-name>.chinacloudsites.cn/tables/TodoItem 格式的 GET 查询,查询移动后端。(Optional) Use a REST tool such as Fiddler or Postman to query your mobile backend, using a GET query in the form https://<your-mobile-app-backend-name>.chinacloudsites.cn/tables/TodoItem.

更新应用以重新连接移动应用后端Update the app to reconnect your Mobile App backend

本部分将应用重新连接到移动应用后端。In this section, reconnect the app to the mobile app backend. 这模拟的是通过移动应用后端从脱机状态转为联机状态的应用。This simulates the app moving from an offline state to an online state with the mobile app backend. 如果是通过关闭网络连接来模拟网络中断,则不需更改任何代码。If you simulated the network breakage by turning off network connectivity, no code changes are needed. 重新打开网络。Turn the network on again. 首次运行该应用程序时,调用 RefreshDataAsync 方法。When you first run the application, the RefreshDataAsync method is called. 而此操作又将调用 SyncAsync ,将本地存储与后端数据库同步。This in turn calls SyncAsync to sync your local store with the backend database.

  1. 在共享项目中,打开 QSToDoService.cs,撤消对 applicationURL 属性所做的更改。Open QSToDoService.cs in the shared project, and revert your change of the applicationURL property.

  2. 构建并运行应用程序。Rebuild and run the app. 执行 OnRefreshItemsSelected 方法时,应用使用推送和拉取操作将本地更改与 Azure 移动应用后端同步。The app syncs your local changes with the Azure Mobile App backend using push and pull operations when the OnRefreshItemsSelected method executes.

  3. (可选)使用 SQL Server 对象资源管理器或 Fiddler 之类的 REST 工具查看更新后的数据。(Optional) View the updated data using either SQL Server Object Explorer or a REST tool like Fiddler. 请注意,数据已在 Azure 移动应用后端数据库和本地存储之间进行同步。Notice the data has been synchronized between the Azure Mobile App backend database and the local store.

  4. 在应用程序中,单击要在本地存储区中完成的几个项旁边的复选框。In the app, click the check box beside a few items to complete them in the local store.

    CompleteItemAsync 调用 SyncAsync,将每个已完成项与移动应用后端同步。CompleteItemAsync calls SyncAsync to sync each completed item with the Mobile App backend. SyncAsync 同时调用推送和拉取操作。SyncAsync calls both push and pull. 每当对客户端已更改的表执行拉取操作时,始终先对客户端同步上下文自动执行推送操作 。Whenever you execute a pull against a table that the client has made changes to, a push on the client sync context is always executed first automatically. 隐式推送可确保本地存储中的所有表以及关系都保持一致。The implicit push ensures all tables in the local store along with relationships remain consistent. 有关此行为的详细信息,请参阅 Azure 移动应用中的脱机数据同步For more information on this behavior, see Offline Data Sync in Azure Mobile Apps.

查看客户端同步代码Review the client sync code

完成教程 创建 Xamarin iOS 应用 时下载的 Xamarin 客户端项目已包含使用本地 SQLite 数据库支持脱机同步的代码。The Xamarin client project that you downloaded when you completed the tutorial Create a Xamarin iOS app already contains code supporting offline synchronization using a local SQLite database. 下面简要概述了在教程代码中已包含的内容。Here is a brief overview of what is already included in the tutorial code. 有关功能的概念性概述,请参阅 Azure 移动应用中的脱机数据同步For a conceptual overview of the feature, see Offline Data Sync in Azure Mobile Apps.

  • 表操作之前,必须初始化本地存储区。Before any table operations can be performed, the local store must be initialized. QSTodoListViewController.ViewDidLoad() 执行 QSTodoService.InitializeStoreAsync() 时,对本地存储数据库进行初始化。The local store database is initialized when QSTodoListViewController.ViewDidLoad() executes QSTodoService.InitializeStoreAsync(). 此方法将使用 Azure 移动应用客户端 SDK 提供的 MobileServiceSQLiteStore 类创建一个新的本地 SQLite 数据库。This method creates a new local SQLite database using the MobileServiceSQLiteStore class provided by the Azure Mobile App client SDK.

    DefineTable 方法与所提供类型(此例中为 ToDoItem)中的字段相匹配的本地存储中创建一个表。The DefineTable method creates a table in the local store that matches the fields in the provided type, ToDoItem in this case. 该类型无需包括远程数据库中的所有列。The type doesn't have to include all the columns that are in the remote database. 可以只存储列的子集。It is possible to store just a subset of columns.

      // QSTodoService.cs
      public async Task InitializeStoreAsync()
          var store = new MobileServiceSQLiteStore(localDbPath);
          // Uses the default conflict handler, which fails on conflict
          await client.SyncContext.InitializeAsync(store);
  • QSTodoServicetodoTable 成员属于 IMobileServiceSyncTable 类型而不是 IMobileServiceTable 类型。The todoTable member of QSTodoService is of the IMobileServiceSyncTable type instead of IMobileServiceTable. IMobileServiceSyncTable 会将所有创建、读取、更新和删除 (CRUD) 表操作定向到本地存储数据库。The IMobileServiceSyncTable directs all create, read, update, and delete (CRUD) table operations to the local store database.

    通过调用 IMobileServiceSyncContext.PushAsync()确定将这些更改推送到 Azure 移动应用后端的时间。You decide when those changes are pushed to the Azure Mobile App backend by calling IMobileServiceSyncContext.PushAsync(). 对于调用 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.

    每当刷新 todoitem 列表或者添加或完成 todoitem 时,所提供的代码便会调用 QSTodoService.SyncAsync() 进行同步。The provided code calls QSTodoService.SyncAsync() to sync whenever the todoitem list is refreshed or a todoitem is added or completed. 该应用在每次本地更改后同步。The app syncs after every local change. 如果对具有由上下文跟踪的未完成本地更新的表执行拉取操作,该拉取操作自动先触发上下文推送操作。If a pull is executed against a table that has pending local updates tracked by the context, that pull operation will automatically trigger a context push first.

    在所提供的代码中,将查询远程 TodoItem 表中的所有记录,但它还可以筛选记录,只需将查询 ID 和查询传递给 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. 有关详细信息,请参阅 Azure 移动应用中的脱机数据同步 中的 增量同步部分。For more information, see the section Incremental Sync in Offline Data Sync in Azure Mobile Apps.

      // QSTodoService.cs
      public async Task SyncAsync()
              await client.SyncContext.PushAsync();
              await todoTable.PullAsync("allTodoItems", todoTable.CreateQuery()); // query ID is used for incremental sync
          catch (MobileServiceInvalidOperationException e)
              Console.Error.WriteLine(@"Sync Failed: {0}", e.Message);

其他资源Additional Resources