Cordova モバイル アプリのオフライン同期を有効にする
概要
このチュートリアルでは、Cordova 向けの Azure Mobile Apps のオフライン同期機能について説明します。 オフライン同期を使用すると、エンド ユーザーはネットワークにアクセスできなくても、データの表示、追加、変更など、モバイル アプリとやり取りできます。 変更は、ローカル データベースに格納されます。 デバイスが再びオンラインになると、これらの変更がリモート サービスと同期されます。
このチュートリアルは、チュートリアル「 Apache Cordova クイック スタート」を完了した際に作成される Mobile Apps 用の Cordova クイック スタート ソリューションに基づいています。 このチュートリアルでは、クイックスタート ソリューションを更新して、Azure Mobile Apps のオフライン機能を追加します。 また、アプリのオフライン固有のコードについても取り上げます。
オフラインの同期機能の詳細については、トピック「 Azure Mobile Apps でのオフライン データ同期」をご覧ください。 API 使用量の詳細については、API ドキュメントをご覧ください。
クイック スタート ソリューションへのオフライン同期の追加
オフライン同期コードは、アプリに追加する必要があります。 オフライン同期には、cordova-sqlite-storage プラグインが必要です。このプラグインは、Azure Mobile Apps プラグインがプロジェクトに含まれる場合に、自動的にアプリに追加されます。 クイック スタート プロジェクトには、これらの両方のプラグインが含まれています。
Visual Studio のソリューション エクスプローラーで index.js を開き、次のコードを
var client, // Connection to the Azure Mobile App backend todoItemTable; // Reference to a table endpoint on backend
次のコードに置き換えます。
var client, // Connection to the Azure Mobile App backend todoItemTable, // Reference to a table endpoint on backend syncContext; // Reference to offline data sync context
次に、次のコードを
client = new WindowsAzure.MobileServiceClient('http://yourmobileapp.azurewebsites.net');
次のコードに置き換えます。
client = new WindowsAzure.MobileServiceClient('http://yourmobileapp.azurewebsites.net'); var store = new WindowsAzure.MobileServiceSqliteStore('store.db'); store.defineTable({ name: 'todoitem', columnDefinitions: { id: 'string', text: 'string', complete: 'boolean', version: 'string' } }); // Get the sync context from the client syncContext = client.getSyncContext();
上記のコードの追加によって、ローカル ストアが初期化され、Azure バックエンドで使用される列の値が一致するローカル テーブルが定義されます (このコードにすべての列値を含める必要はありません)。フィールドは
version
モバイル バックエンドによって管理され、競合の解決に使用されます。同期コンテキストへの参照を取得するには、 getSyncContextを呼び出します。 同期コンテキストは、
.push()
が呼び出されたときに、クライアント アプリが変更を行ったすべてのテーブルで、変更を追跡およびプッシュすることで、テーブルの関係を保持するのに役立ちます。アプリケーションの URL を Mobile App アプリケーションの URL に更新します。
次に、次のコードを
todoItemTable = client.getTable('todoitem'); // todoitem is the table name
次のコードに置き換えます。
// Initialize the sync context with the store syncContext.initialize(store).then(function () { // Get the local table reference. todoItemTable = client.getSyncTable('todoitem'); syncContext.pushHandler = { onConflict: function (pushError) { // Handle the conflict. console.log("Sync conflict! " + pushError.getError().message); // Update failed, revert to server's copy. pushError.cancelAndDiscard(); }, onError: function (pushError) { // Handle the error // In the simulated offline state, you get "Sync error! Unexpected connection failure." console.log("Sync error! " + pushError.getError().message); } }; // Call a function to perform the actual sync syncBackend(); // Refresh the todoItems refreshDisplay(); // Wire up the UI Event Handler for the Add Item $('#add-item').submit(addItemHandler); $('#refresh').on('click', refreshDisplay);
上記のコードは、同期コンテキストを初期化してから、getSyncTable を (getTable の代わりに) 呼び出して、ローカル テーブルへの参照を取得します。
このコードでは、作成、読み取り、更新、削除 (CRUD) のすべてのテーブル操作にローカル データベースを使用します。
このサンプルでは、同期の競合に対して、単純なエラー処理を実行します。 実際のアプリケーションでは、ネットワーク状態、サーバーの競合などの各種エラーが処理されます。 コード例については、 オフライン同期サンプルを参照してください。
次に、実際の同期を実行する関数を追加します。
function syncBackend() { // Sync local store to Azure table when app loads, or when login complete. syncContext.push().then(function () { // Push completed }); // Pull items from the Azure table after syncing to Azure. syncContext.pull(new WindowsAzure.Query('todoitem')); }
変更をいつ Mobile App バックエンドにプッシュするかは、syncContext.push() を呼び出すことによって決定します。 たとえば、同期ボタンに関連付けられているボタンのイベント ハンドラーで syncBackend を呼び出すことが可能です。
オフライン同期に関する考慮事項
サンプルでは、syncContext の push メソッドが、アプリの起動時だけにログインのコールバック関数で呼び出されます。 実際のアプリケーションでは、手動で、またはネットワークの状態が変更されたときに、この同期機能がトリガーされるように設定することもできます。
コンテキストによって追跡された保留中のローカル更新のあるテーブルに対してプルが実行された場合、そのプル操作は自動的にプッシュをトリガーします。 このサンプルの項目を更新、追加、完了するとき、明示的な push の呼び出しは省略できます。冗長であるためです。
提供されたコードでは、リモートの todoItem テーブルのすべてのレコードが照会されますが、クエリ ID とクエリを pushに渡すことでレコードをフィルター処理することも可能です。 詳細については、「 Azure Mobile Apps でのオフライン データ同期 」の「 Azure Mobile Apps でのオフライン データ同期」セクションを参照してください。
(省略可能) 認証の無効化
オフライン同期のテスト前に認証をセットアップしない場合は、ログインのコールバック関数をコメント アウトします。ただし、コールバック関数内のコードはコメント化しないままにしておきます。 ログイン行をコメント アウトすると、コードは次のようになります。
// Login to the service.
// client.login('twitter')
// .then(function () {
syncContext.initialize(store).then(function () {
// Leave the rest of the code in this callback function uncommented.
...
});
// }, handleError);
これで、アプリの実行時にアプリが Azure バックエンドと同期するようになります。
クライアント アプリの実行
オフライン同期が有効になったので、各プラットフォームで少なくとも 1 回クライアント アプリケーションを実行すると、ローカル ストア データベースにデータが設定されるようになりました。 この後、オフラインのシナリオをシミュレートし、アプリがオフラインの間にローカル ストアのデータを変更します。
(省略可能) 同期の動作のテスト
このセクションでは、バックエンドに無効なアプリケーション URL を使用することで、クライアント プロジェクトを変更して、オフラインのシナリオをシミュレートします。 データ項目を追加または変更すると、これらの変更はローカル ストアに保持されますが、接続が再確立されるまでは、バックエンドのデータ ストアには同期されません。
ソリューション エクスプローラーで、index.js プロジェクト ファイルを開き、次のコードのように、無効な URL を指すようにアプリケーション URL を変更します。
client = new WindowsAzure.MobileServiceClient('http://yourmobileapp.azurewebsites.net-fail');
index.html で、CSP
<meta>
要素を同じ無効な URL に更新します。<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: http://yourmobileapp.azurewebsites.net-fail; style-src 'self'; media-src *">
クライアント アプリをビルドして実行し、アプリがログイン後にバックエンドと同期を試みるたびに、コンソールに例外がログ記録されることを確認してください。 追加した新しい項目は、モバイルのバックエンドにプッシュされるまでローカル ストアにのみ存在します。 クライアント アプリは、バックエンドに接続されているかのように動作します。
アプリケーションを終了し、再起動して、作成した新しい項目がローカル ストアに保存されていることを確認します。
(省略可能) Visual Studio を使用して、Azure SQL Database テーブルを表示し、バックエンドのデータベースのデータが変更されていないことを確認します。
Visual Studio で、 サーバー エクスプローラーを開きます。 Azure-SQL> データベース内のデータベースに移動します。 データベースを右クリックし、 [SQL Server オブジェクト エクスプローラーで開く] を選択します。 これで SQL データベースのテーブルとその内容を参照できます。
(省略可能) モバイル バックエンドへの再接続のテスト
このセクションでは、アプリケーションをモバイル バックエンドに再接続して、アプリケーションがオンライン状態に戻ったときの動作をシミュレーションします。 ログインすると、データがモバイル バックエンドに同期されます。
index.js をもう一度開き、アプリケーション URL を復元します。
index.html をもう一度開き、CSP
<meta>
要素のアプリケーション URL を修正します。クライアント アプリの再構築と実行 ログイン後、アプリはモバイル アプリ バックエンドとの同期を試みます。 デバッグ コンソールに例外がログ記録されていないことを確認してください。
(省略可能) SQL Server Object Explorer または Fiddler などの REST ツールを使用して、更新データを表示します。 バックエンド データベースとローカル ストアの間でデータが同期されていることを確認します。
データがデータベースとローカル ストアの間で同期されており、アプリが接続されていない状況で追加した項目が含まれていることを確認してください。
その他のリソース
次のステップ
- オフライン同期サンプルで、競合解決など、より高度なオフライン同期機能について学びます。
- API ドキュメントで、オフライン同期 API リファレンスを確認します。