次の方法で共有


Azure Mobile Apps でのオフライン データ同期

オフライン データ同期とは

オフライン データ同期は、Azure Mobile Apps のクライアントとサーバー SDK の機能であり、開発者はネットワーク接続なしで機能するアプリを簡単に作成できます。

アプリがオフライン モードの場合でも、ローカル ストアに保存されるデータを作成および変更できます。 アプリがオンラインに戻ると、ローカルの変更を Azure Mobile App バックエンドと同期できます。 この機能には、クライアントとバックエンドの両方で同じレコードが変更されたときに競合を検出するためのサポートも含まれています。 その後、サーバーまたはクライアントで競合を処理できます。

オフライン同期には、いくつかの利点があります。

  • デバイス上のサーバー データをローカルにキャッシュすることで、アプリの応答性を向上させる
  • ネットワークの問題がある場合に役立つ堅牢なアプリを作成する
  • ネットワーク アクセスがない場合でもエンド ユーザーがデータを作成および変更できるようにする(接続がほとんどまたはまったくないシナリオをサポートする)
  • 複数のデバイス間でデータを同期し、同じレコードが 2 つのデバイスによって変更されたときに競合を検出する
  • 待機時間の長いネットワークまたは従量制課金ネットワークでのネットワーク使用を制限する

次のチュートリアルでは、Azure Mobile Apps を使用してモバイル クライアントにオフライン同期を追加する方法について説明します。

同期テーブルとは

"/tables" エンドポイントにアクセスするために、Azure Mobile クライアント SDK には、IMobileServiceTable (.NET クライアント SDK) や MSTable (iOS クライアント) などのインターフェイスが用意されています。 これらの API は Azure Mobile App バックエンドに直接接続され、クライアント デバイスにネットワーク接続がない場合は失敗します。

オフラインでの使用をサポートするには、IMobileServiceSyncTable (.NET クライアント SDK) や MSSyncTable (iOS クライアント) などの API 同期テーブルを使用する必要があります。 すべての同じ CRUD 操作 (作成、読み取り、更新、削除) は、同期テーブル API に対して機能します。ただし、ローカル ストアに対して読み取りまたは書き込みを行う点が異なります。 同期テーブルの操作を実行する前に、ローカル ストアを初期化する必要があります。

ローカル ストアとは

ローカル ストアは、クライアント デバイス上のデータ永続化レイヤーです。 Azure Mobile Apps クライアント SDK には、既定のローカル ストア実装が用意されています。 Windows、Xamarin、Android では、SQLite に基づいています。 iOS では、コア データに基づいています。

Windows Phone または Microsoft Store で SQLite ベースの実装を使用するには、SQLite 拡張機能をインストールする必要があります。 詳細については、「ユニバーサル Windows プラットフォーム: オフライン同期を有効にする」を参照してください。Android および iOS には、デバイス オペレーティング システム自体に SQLite のバージョンが付属しているため、独自のバージョンの SQLite を参照する必要はありません。

開発者は、独自のローカル ストアを実装することもできます。 たとえば、モバイル クライアントに暗号化された形式でデータを格納する場合は、暗号化に SQLCipher を使用するローカル ストアを定義できます。

同期コンテキストとは

同期コンテキスト はモバイル クライアント オブジェクト (IMobileServiceClientMSClientなど) に関連付け、同期テーブルで行われた変更を追跡します。 同期コンテキストは、後でサーバーに送信される CUD 操作 (作成、更新、削除) の順序付きリストを保持する、操作キューを保持します。

ローカル ストアは、.NET クライアント SDKIMobileServicesSyncContext.InitializeAsync(localstore) などの初期化メソッドを使用して同期コンテキストに関連付けられます。

オフライン同期のしくみ

同期テーブルを使用する場合、クライアント コードはローカルの変更を Azure Mobile App バックエンドと同期するタイミングを制御します。 ローカルの変更をプッシュする が呼び出されるまで、 バックエンドには何も送信されません。 同様に、ローカル ストアには、データをプルする 呼び出しがある場合にのみ、新しいデータが登録されます。

  • プッシュ: プッシュは同期コンテキストに対する操作であり、前回のプッシュ以降のすべての CUD 変更を送信します。 それ以外の場合、操作が順不同で送信される可能性があるため、個々のテーブルの変更のみを送信することはできません。 プッシュは、Azure Mobile App バックエンドに対して一連の REST 呼び出しを実行し、サーバー データベースを変更します。

  • プル: プルはテーブルごとに実行され、クエリを使用してカスタマイズして、サーバー データのサブセットのみを取得できます。 その後、Azure Mobile クライアント SDK によって、結果のデータがローカル ストアに挿入されます。

  • 暗黙的なプッシュ: 保留中のローカル更新があるテーブルに対してプルが実行された場合、プルは最初に同期コンテキストで push() を実行します。 このプッシュは、既にキューに登録されている変更とサーバーからの新しいデータの間の競合を最小限に抑えるのに役立ちます。

  • 増分同期: プル操作の最初のパラメーターは、クライアントでのみ使用される クエリ名 です。 null 以外のクエリ名を使用する場合、Azure Mobile SDK は 増分同期を実行します。プル操作が一連の結果を返すたびに、その結果セットの最新の updatedAt タイムスタンプが SDK ローカル システム テーブルに格納されます。 後続のプル操作では、そのタイムスタンプの後のレコードのみが取得されます。

    増分同期を使用するには、サーバーは意味のある updatedAt 値を返す必要があり、このフィールドによる並べ替えもサポートする必要があります。 ただし、SDK は updatedAt フィールドに独自の並べ替えを追加するため、独自の orderBy 句を持つプル クエリを使用することはできません。

    クエリ名には任意の文字列を指定できますが、アプリ内の論理クエリごとに一意である必要があります。 そうしないと、異なるプル操作によって同じ増分同期タイムスタンプが上書きされ、クエリから正しくない結果が返される可能性があります。

    クエリにパラメーターがある場合、一意のクエリ名を作成する 1 つの方法は、パラメーター値を組み込むことです。 たとえば、userid でフィルター処理する場合、クエリ名は次のようになります (C# の場合)。

      await todoTable.PullAsync("todoItems" + userid,
          syncTable.Where(u => u.UserId == userid));
    

    増分同期を無効にする場合は、クエリ ID として null 渡します。 この場合、PullAsyncの呼び出しごとにすべてのレコードが取得されます。これは非効率的である可能性があります。

  • 消去: IMobileServiceSyncTable.PurgeAsyncを使用してローカル ストアの内容をクリアできます。 クライアント データベースに古いデータがある場合、または保留中のすべての変更を破棄する場合は、消去が必要な場合があります。

    消去により、ローカル ストアからテーブルがクリアされます。 サーバー データベースとの同期を待機している操作がある場合、強制消去 パラメーターが設定されていない限り、消去は例外をスローします。

    クライアント上の古いデータの例として、"todo list" の例では、Device1 は完了していない項目のみをプルするとします。 todoitem "Buy milk" は、別のデバイスによってサーバー上で完了済みとしてマークされます。 ただし、Device1 は、完了とマークされていないアイテムのみをプルするため、ローカル ストアに "ミルクの購入" todoitem が引き続き存在します。 消去によって、この古い項目がクリアされます。

次のステップ