- アンドロイド
- コルドバ
- iOS
- ウィンドウズ
- Xamarin.Android
- Xamarin.Forms
- Xamarin.iOS
概要
このチュートリアルでは、Xamarin.Forms 用 Azure Mobile Apps のオフライン同期機能について説明します。 オフライン同期を使用すると、エンド ユーザーは、ネットワーク接続がない場合でも、モバイル アプリの表示、追加、変更など、データを操作できます。 変更はローカル データベースに格納されます。 デバイスがオンラインに戻ると、これらの変更はリモート サービスと同期されます。
このチュートリアルは、チュートリアル [Xamarin iOS アプリの作成] を完了したときに作成する Mobile Apps の Xamarin.Forms クイック スタート ソリューションに基づいています。 Xamarin.Forms のクイック スタート ソリューションには、オフライン同期をサポートするコードが含まれています。このコードは有効にする必要があります。 このチュートリアルでは、クイック スタート ソリューションを更新して、Azure Mobile Apps のオフライン機能を有効にします。 また、アプリ内のオフライン固有のコードも強調表示します。 ダウンロードしたクイック スタート ソリューションを使用しない場合は、データ アクセス拡張機能パッケージをプロジェクトに追加する必要があります。 サーバー拡張機能パッケージの詳細については、「 .NET バックエンド サーバー SDK for Azure Mobile Apps の操作」を参照してください。
オフライン同期機能の詳細については、 Azure Mobile Apps でのオフライン データ同期に関するトピックを参照してください。
クイック スタート ソリューションでオフライン同期機能を有効にする
オフライン同期コードは、C# プリプロセッサ ディレクティブを使用してプロジェクトに含まれます。 OFFLINE_SYNC_ENABLEDシンボルが定義されると、これらのコード パスがビルドに含まれます。 Windows アプリの場合は、SQLite プラットフォームもインストールする必要があります。
Visual Studio でソリューション >Manage NuGet Packages for Solution...] を右クリックし、ソリューション内のすべてのプロジェクトの Microsoft.Azure.Mobile.Client.SQLiteStore NuGet パッケージを検索してインストールします。
ソリューション エクスプローラーで、プロジェクトの TodoItemManager.cs ファイルを Portable という 名前 (ポータブル クラス ライブラリ プロジェクト) で開き、次のプリプロセッサ ディレクティブのコメントを解除します。
#define OFFLINE_SYNC_ENABLED
(省略可能)Windows デバイスをサポートするには、次のいずれかの SQLite ランタイム パッケージをインストールします。
Windows 8.1 ランタイム:SQLite for Windows 8.1 をインストールします。
Windows Phone 8.1:Windows Phone 8.1 用 SQLite をインストールします。
ユニバーサル Windows プラットフォームユニバーサル Windows ユニバーサル用の SQLite をインストールします。
クイックスタートにはユニバーサル Windows プロジェクトは含まれていませんが、ユニバーサル Windows プラットフォームは Xamarin Forms でサポートされています。
(省略可能)各 Windows アプリ プロジェクトで、[ 参照>参照の追加...] を右クリックし、 Windows フォルダー >Extensions を展開します。 Windows SDK 用の適切な SQLite と Visual C++ 2013 Runtime for Windows SDK を有効にします。 SQLite SDK の名前は、Windows プラットフォームごとに若干異なります。
クライアント同期コードを確認する
#if OFFLINE_SYNC_ENABLED
ディレクティブ内のチュートリアル コードに既に含まれている内容の簡単な概要を次に示します。 オフライン同期機能は、ポータブル クラス ライブラリ プロジェクトのTodoItemManager.cs プロジェクト ファイルにあります。 この機能の概念の概要については、「 Azure Mobile Apps でのオフライン データ同期」を参照してください。
テーブル操作を実行する前に、ローカル ストアを初期化する必要があります。 ローカル ストア データベースは、次のコードを使用して TodoItemManager クラス コンストラクターで初期化されます。
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 データベースを作成します。
DefineTable メソッドは、指定された型のフィールドと一致するテーブルをローカル ストアに作成します。 型には、リモート データベース内のすべての列を含める必要はありません。 列のサブセットを格納できます。
TodoItemManager の todoTable フィールドは、IMobileServiceTable ではなく IMobileServiceSyncTable 型です。 このクラスは、すべての作成、読み取り、更新、および削除 (CRUD) テーブル操作にローカル データベースを使用します。 これらの変更がモバイル アプリ バックエンドにプッシュされるタイミングを決定するには、IMobileServiceSyncContext で PushAsync を呼び出します。 同期コンテキストは、 PushAsync が呼び出されたときにクライアント アプリが変更したすべてのテーブルの変更を追跡およびプッシュすることで、テーブルのリレーションシップを保持するのに役立ちます。
モバイル アプリ バックエンドと同期するために、次の SyncAsync メソッドが呼び出されます。
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"]); } } }
このサンプルでは、既定の同期ハンドラーで単純なエラー処理を使用します。 実際のアプリケーションでは、カスタム IMobileServiceSyncHandler 実装を使用して、ネットワーク条件やサーバーの競合などのさまざまなエラーを処理します。
オフライン同期に関する考慮事項
このサンプルでは、 SyncAsync メソッドは起動時と同期が要求されたときにのみ呼び出されます。 Android または iOS アプリで同期を開始するには、項目の一覧をプルダウンします。Windows の場合は、[ 同期 ] ボタンを使用します。 実際のアプリケーションでは、ネットワークの状態が変化したときに同期トリガーを行うこともできます。
保留中のローカル更新がコンテキストによって追跡されているテーブルに対してプルが実行されると、そのプル操作によって、前のコンテキスト プッシュが自動的にトリガーされます。 このサンプルの項目を更新、追加、完了するときに、明示的な PushAsync 呼び出しを省略できます。
指定されたコードでは、リモートの TodoItem テーブル内のすべてのレコードがクエリされますが、クエリ ID とクエリを PushAsync に渡すことでレコードをフィルター処理することもできます。 詳細については、「Azure Mobile Apps でのオフライン データ同期での増分同期」セクションを参照してください。
クライアント アプリを実行する
オフライン同期が有効になったので、各プラットフォームでクライアント アプリケーションを少なくとも 1 回実行して、ローカル ストア データベースを設定します。 後でオフライン シナリオをシミュレートし、アプリがオフラインの間にローカル ストア内のデータを変更します。
クライアント アプリの同期動作を更新する
このセクションでは、バックエンドの無効なアプリケーション URL を使用してオフライン シナリオをシミュレートするようにクライアント プロジェクトを変更します。 または、デバイスを "機内モード" に移動して、ネットワーク接続をオフにすることもできます。データ項目を追加または変更すると、これらの変更はローカル ストアに保持されますが、接続が再確立されるまでバックエンド データ ストアに同期されません。
ソリューション エクスプローラーで、 Portable プロジェクトから Constants.cs プロジェクト ファイルを開き、無効な URL を指すように
ApplicationURL
の値を変更します。public static string ApplicationURL = @"https://your-service.azurewebsites.net/";
Portable プロジェクトから TodoItemManager.cs ファイルを開き、SyncAsync 内の try...catch ブロックに基本 Exception クラスの catch を追加します。 この catch ブロックは、次のように例外メッセージをコンソールに書き込みます。
catch (Exception ex) { Console.Error.WriteLine(@"Exception: {0}", ex.Message); }
クライアント アプリをビルドして実行します。 新しい項目をいくつか追加します。 バックエンドとの同期を試行するたびに、コンソールに例外が記録されていることに注意してください。 これらの新しい項目は、モバイル バックエンドにプッシュできるようになるまでローカル ストアにのみ存在します。 クライアント アプリはバックエンドに接続されているかのように動作し、すべての作成、読み取り、更新、削除 (CRUD) 操作をサポートします。
アプリを閉じて再起動し、作成した新しい項目がローカル ストアに保存されていることを確認します。
(省略可能)Visual Studio を使用して Azure SQL Database テーブルを表示し、バックエンド データベース内のデータが変更されていないことを確認します。
Visual Studio で、 サーバー エクスプローラーを開きます。 Azure->SQL データベース内のデータベースに移動します。 データベースを右クリックし、[ SQL Server オブジェクト エクスプローラーで開く] を選択します。 これで、SQL データベーステーブルとその内容を参照できます。
クライアント アプリを更新してモバイル バックエンドを再接続する
このセクションでは、アプリをモバイル バックエンドに再接続します。これにより、オンライン状態に戻るアプリがシミュレートされます。 更新ジェスチャを実行すると、データはモバイル バックエンドに同期されます。
Constants.csを再度開きます。 正しい URL をポイントするように
applicationURL
を修正します。クライアント アプリをリビルドして実行します。 アプリは、起動後にモバイル アプリ バックエンドとの同期を試みます。 デバッグ コンソールに例外が記録されていないことを確認します。
(省略可能)SQL Server オブジェクト エクスプローラーまたは Fiddler や Postman などの REST ツールを使用して、更新されたデータを表示します。 バックエンド データベースとローカル ストアの間でデータが同期されていることに注意してください。
データがデータベースとローカル ストアの間で同期され、アプリが切断されている間に追加した項目が含まれていることに注意してください。
その他のリソース
- Azure Mobile Apps でのオフライン データ同期機能
- Azure Mobile Apps .NET SDK の使用方法