Xamarin.Forms モバイル アプリのオフライン同期の有効化Enable offline sync for your Xamarin.Forms mobile app

注意

Visual Studio App Center では、モバイル アプリ開発の中心となる新しい統合サービスに投資しています。Visual Studio App Center is investing in new and integrated services central to mobile app development. 開発者は、ビルドテスト配布のサービスを使用して、継続的インテグレーションおよびデリバリー パイプラインを設定できます。Developers can use Build, Test and Distribute services to set up Continuous Integration and Delivery pipeline. アプリがデプロイされたら、開発者は分析および診断のサービスを利用してアプリの状態と使用状況を監視し、プッシュ サービスを利用してユーザーと関わることができます。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. また、開発者は Auth を利用してユーザーを認証し、データ サービスを利用してクラウド内のアプリ データを保持および同期することもできます。Developers can also leverage Auth to authenticate their users and Data service to persist and sync app data in the cloud. App Center を今すぐチェックしてください。Check out App Center today.

概要Overview

このチュートリアルでは、Xamarin.Forms 向けの Azure Mobile Apps のオフライン同期機能について説明します。This tutorial introduces the offline sync feature of Azure Mobile Apps for Xamarin.Forms. オフライン同期を使用すると、エンド ユーザーはネットワークにアクセスできなくても、データの表示、追加、変更など、モバイル アプリケーションとやり取りできます。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 アプリを作成する」を完了した際に作成される Mobile Apps 用の Xamarin.Forms クイック スタート ソリューションに基づいています。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]. この Xamarin.Forms のクイック スタート ソリューションには、オフライン同期をサポートするためのコードが含まれています。これを有効にする必要があります。The quickstart solution for Xamarin.Forms contains the code to support offline sync, which just needs to be enabled. このチュートリアルでは、クイック スタート ソリューションを更新して、Azure Mobile Apps のオフライン機能をオンにします。In this tutorial, you update the quickstart solution to turn on the offline features of Azure Mobile Apps. また、アプリのオフライン固有のコードについても取り上げます。We also highlight the offline-specific code in the app. ダウンロードしたクイック スタート ソリューションを使用しない場合は、データ アクセス拡張機能パッケージをプロジェクトに追加する必要があります。If you do not use the downloaded quickstart solution, you must add the data access extension packages to your project. サーバーの拡張機能パッケージの詳細については、「 Work with the .NET backend server SDK for Azure Mobile Apps (Azure Mobile Apps 用の .NET バックエンド サーバー SDK を操作する)」を参照してください。For more information about server extension packages, see Work with the .NET backend server SDK for Azure Mobile Apps.

オフラインの同期機能の詳細については、トピック「 Azure Mobile Apps でのオフライン データ同期」をご覧ください。To learn more about the offline sync feature, see the topic Offline Data Sync in Azure Mobile Apps.

クイック スタート ソリューションでのオフライン同期機能の有効化Enable offline sync functionality in the quickstart solution

オフライン同期コードは、C# プリプロセッサ ディレクティブを使用してプロジェクトにインクルードされます。The offline sync code is included in the project by using C# preprocessor directives. OFFLINE_SYNC_ENABLED シンボルを定義すると、これらのコード パスがビルドにインクルードされます。When the OFFLINE_SYNC_ENABLED symbol is defined, these code paths are included in the build. Windows アプリの場合、SQLite プラットフォームもインストールする必要があります。For Windows apps, you must also install the SQLite platform.

  1. Visual Studio で、ソリューション、 [ソリューションの NuGet パッケージの管理...] の順に右クリックし、ソリューション内のすべてのプロジェクトの Microsoft.Azure.Mobile.Client.SQLiteStore NuGet パッケージを探してインストールします。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. ソリューション エクスプローラーで、ポータブル クラス ライブラリ プロジェクトである Portable というプロジェクトから TodoItemManager.cs ファイルを開き、次のプリプロセッサ ディレクティブをコメント解除します。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. (省略可能) Windows デバイスをサポートする場合、次の SQLite ランタイム パッケージのいずれかをインストールします。(Optional) To support Windows devices, install one of the following SQLite runtime packages:

  4. (省略可能) それぞれの Windows アプリ プロジェクトで、 [参照] > [参照の追加] の順に右クリックして、Windows フォルダー、 [拡張機能] の順に展開します。(Optional) In each Windows app project, right-click References > Add Reference..., expand the Windows folder > Extensions. 適切な SQLite for Windows SDK と Visual C++ 2013 Runtime for Windows SDK を有効にします。Enable the appropriate SQLite for Windows SDK along with the Visual C++ 2013 Runtime for Windows SDK. Windows プラットフォームによって SQLite SDK の名前はわずかに異なります。The SQLite SDK names vary slightly with each Windows platform.

クライアント同期コードの確認Review the client sync code

ここでは、 #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. オフライン同期機能は、ポータブル クラス ライブラリ プロジェクト内の TodoItemManager.cs プロジェクト ファイル内にあります。The offline sync functionality is in the TodoItemManager.cs project file in the Portable Class Library project. 機能の概念的な概要については、「 Azure Mobile Apps でのオフライン データ同期」をご覧ください。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. ローカル ストア データベースは、次のコードを使用して TodoItemManager クラス コンストラクターで初期化されます。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>();
    

    これにより、 MobileServiceSQLiteStore クラスを使用して新しいローカルの SQLite データベースが作成されます。This code creates a new local SQLite database using the MobileServiceSQLiteStore class.

    DefineTable メソッドを実行すると、提供された型のフィールドに一致するテーブルがローカル ストアに作成されます。The DefineTable method creates a table in the local store that matches the fields in the provided type. この型に、リモート データベース内のすべての列を含める必要はありません。The type doesn't have to include all the columns that are in the remote database. 列のサブセットを格納できます。It is possible to store a subset of columns.

  • TodoItemManagertodoTable フィールドは、IMobileServiceTable 型ではなく IMobileServiceSyncTable 型です。The todoTable field in TodoItemManager is an IMobileServiceSyncTable type instead of IMobileServiceTable. このクラスでは、作成、読み取り、更新、削除 (CRUD) のすべてのテーブル操作にローカル データベースを使用します。This class uses the local database for all create, read, update, and delete (CRUD) table operations. これらの変更がいつモバイル アプリ バックエンドにプッシュされるかを決定するには、IMobileServiceSyncContextPushAsync を呼び出します。You decide when those changes are pushed to the Mobile App backend by calling PushAsync on the IMobileServiceSyncContext. この同期コンテキストは、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.

    次の SyncAsync メソッドは、モバイル アプリ バックエンドと同期するために呼び出されます。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"]);
              }
          }
      }
    

    このサンプルでは、既定の同期ハンドラーを使った単純なエラー処理を使用しています。This sample uses simple error handling with the default sync handler. 実際のアプリケーションでは、ネットワーク状態やサーバーの競合などの各種エラーが、カスタム IMobileServiceSyncHandler の実装を使用して処理されます。A real application would handle the various errors like network conditions and server conflicts by using a custom IMobileServiceSyncHandler implementation.

オフライン同期に関する考慮事項Offline sync considerations

このサンプルでは、SyncAsync メソッドは起動時と同期が明示的に要求された場合にのみ呼び出されます。In the sample, the SyncAsync method is only called on start-up and when a sync is requested. Android アプリまたは iOS アプリで同期を開始するには、項目一覧でプルダウンします。Windows アプリでは、 [同期] ボタンを使用します。To initiate a sync in an Android or iOS app, pull down on the items list; for Windows, use the Sync button. 実際のアプリケーションでは、ネットワークの状態が変更されたときに同期がトリガーされるように設定することもできます。In a real-world application, you could also make the sync trigger when the network state changes.

コンテキストによって追跡された保留中のローカル更新のあるテーブルに対してプルが実行される場合、そのプル操作は前のコンテキストのプッシュを自動的にトリガーします。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. このサンプルの項目を更新、追加、完了するとき、明示的な PushAsync の呼び出しを省略できます。When refreshing, adding, and completing items in this sample, you can omit the explicit PushAsync call.

提供されたコードでは、リモートの 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 Mobile Apps でのオフライン データ同期 」の「 増分同期」セクションを参照してください。For more information, see the section Incremental Sync in Offline Data Sync in Azure Mobile Apps.

クライアント アプリの実行Run the client app

オフライン同期が有効になったので、各プラットフォームで少なくとも 1 回クライアント アプリケーションを実行して、ローカル ストア データベースにデータを設定します。With offline sync now enabled, run the client application at least once on each platform to populate the local store database. この後、オフラインのシナリオをシミュレートし、アプリがオフラインの間にローカル ストアのデータを変更します。Later, simulate an offline scenario and modify the data in the local store while the app is offline.

クライアント アプリの同期の動作を更新するUpdate the sync behavior of the client app

このセクションでは、バックエンドに無効なアプリケーション URL を使用することで、クライアント プロジェクトを変更して、オフラインのシナリオをシミュレートします。In this section, modify the client project to simulate an offline scenario by using an invalid application URL for your backend. デバイスを "機内モード" にすることで、ネットワーク接続をオフにする方法もあります。Alternatively, you can turn off network connections by moving your device to "Airplane mode." データ項目を追加または変更すると、これらの変更はローカル ストアに保持されますが、接続が再確立されるまでは、バックエンドのデータ ストアには同期されません。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. ソリューション エクスプローラーで、Portable プロジェクトから Constants.cs プロジェクト ファイルを開き、ApplicationURL の値を次のような無効な URL を指すように変更します。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. Portable プロジェクトから TodoItemManager.cs ファイルを開き、ベース Exception クラスの catch を、SyncAsync 内の try...catch ブロックに追加します。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. この catch ブロックによってコンソールに例外メッセージが書き込まれます。これは次のようになります。This catch block writes the exception message to the console, as follows:

         catch (Exception ex)
         {
             Console.Error.WriteLine(@"Exception: {0}", ex.Message);
         }
    
  3. クライアント アプリの構築と実行Build and run the client app. 新しい項目をいくつか追加します。Add some new items. バックエンドとの同期を試みるたびに、コンソールに例外がログ記録されることに注意してください。Notice that an exception is logged in the console for each attempt to sync with the backend. これらの新しい項目は、モバイル バックエンドにプッシュされるまでは、ローカル ストア内にのみ存在します。These new items exist only in the local store until they can be pushed to the mobile backend. クライアント アプリケーションは、バックエンドに接続されているかのように動作し、作成、読み取り、更新、削除 (CRUD) 操作のすべてをサポートします。The client app behaves as if it is connected to the backend, supporting all create, read, update, delete (CRUD) operations.

  4. アプリケーションを終了し、再起動して、作成した新しい項目がローカル ストアに保存されていることを確認します。Close the app and restart it to verify that the new items you created are persisted to the local store.

  5. (省略可能) Visual Studio を使用して、Azure SQL Database テーブルを表示し、バックエンドのデータベースのデータが変更されていないことを確認します。(Optional) Use Visual Studio to view your Azure SQL Database table to see that the data in the backend database has not changed.

    Visual Studio で、 サーバー エクスプローラーを開きます。In Visual Studio, open Server Explorer. [Azure] -> [SQL Databases] を選択して、データベースに移動します。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.

クライアント アプリを更新し、モバイルのバックエンドを再接続します。Update the client app to reconnect your mobile backend

このセクションでは、アプリケーションをモバイル バックエンドに再接続して、アプリケーションがオンライン状態に戻ったときの動作をシミュレーションします。In this section, reconnect the app to the mobile backend, which simulates the app coming back to an online state. 更新ジェスチャを実行すると、データがモバイル バックエンドに同期されます。When you perform the refresh gesture, data is synced to your mobile backend.

  1. Constants.cs をもう一度開きます。Reopen Constants.cs. applicationURL を修正して、正しい URL に設定します。Correct the applicationURL to point to the correct URL.

  2. クライアント アプリの再構築と実行Rebuild and run the client app. 起動後、アプリはモバイル アプリ バックエンドとの同期を試みます。The app attempts to sync with the mobile app backend after launching. デバッグ コンソールに例外がログ記録されていないことを確認してください。Verify that no exceptions are logged in the debug console.

  3. (省略可能) SQL Server オブジェクト エクスプローラー、または Fiddler や Postman などの REST ツールを使用して、更新データを表示します。(Optional) View the updated data using either SQL Server Object Explorer or a REST tool like Fiddler or Postman. バックエンド データベースとローカル ストアの間でデータが同期されていることを確認します。Notice the data has been synchronized between the backend database and the local store.

    データがデータベースとローカル ストアの間で同期されており、アプリが接続されていない状況で追加した項目が含まれていることを確認してください。Notice the data has been synchronized between the database and the local store and contains the items you added while your app was disconnected.

その他のリソースAdditional Resources