Share via


iOS 用オフライン同期 SDK の一般提供開始を発表

このポストは、3 月 10 日に投稿された Announcing General Availability of iOS Offline Sync SDK の翻訳です。

エレベーターに乗ったとたんにモバイル アプリの動作が止まって、うんざりした経験はありませんか? または、営業先の顧客のデータをすぐに確認しなければならないのに、電波が届かない場所にいて焦ってしまったことはありませんか? エンド ユーザーが本当に求めているのは、ネットワークが停止しているときでも動作してくれるアプリです。しかし、多くのアプリではデバイスがオフラインになると機能が制限されたり、まったく動作しなくなってしまいます。これは、同期機能を正確に実装することが困難であることが主な理由です。どの項目をデバイスでキャッシュする必要があるのか、どのようにすれば新しいデータを取得するタイミングをアプリで検知できるのか、ユーザーがオフライン中に更新したデータがローカルで既に編集されていた場合にどのような状態になるのかなど、さまざまなことを考慮する必要があるのです。

Mobile Services のオフライン同期機能ではこれらの問題を解決し、クロスプラットフォームのクライアント SDK によって、こうした複雑な状況にすべて対応できるようになっています。Mobile Services を使用すると、iOSAndroidXamarinWindows の各アプリでネイティブな同期エクスペリエンスを簡単に実装できます。

このたび、Mobile Services iOS 2.0 SDK (英語) の一般提供開始が発表され、新たな同期機能を iOS でネイティブに使用できるようになりました。オフライン同期機能は既に Windows、Xamarin iOS、Xamarin Android の各管理クライアント SDK で使用でき、また Android SDK はプレビュー版が使用可能です。Azure ポータルのクイックスタートも更新され、この機能をさらに簡単に使用できるようになっています。さらに、Windows、Xamarin iOS、Xamarin Android と併せて、iOS でも Objective-C のクイックスタートをオフラインで使用できるようになりました。

オフライン同期には、次のような多くのメリットがあります。

  • サーバーのデータをデバイスにキャッシュすることでアプリの応答性が向上
  • ネットワークで一時的な問題が発生した場合にも対応できる堅牢なアプリを構築可能
  • 複数のデバイスの間で同期を実行し、2 つのデバイスで同一のレコードが変更された場合に競合を検出
  • データ使用量を抑制 (特に従量課金制での接続の場合に有効)

アプリがオフライン モードになっている場合でも、ユーザーはデータの作成や修正が可能です。この場合、データはローカル ストアに保存されます。アプリがオンライン状態に戻ると、ローカルで行った変更が Mobile Services バックエンドと同期されます。また、この機能では、同じレコードがクライアントとバックエンドの両方で変更された場合に競合を検出できます。競合が検出された場合は、サーバーかクライアントのいずれかで処理されます。オフライン同期は非常に負荷が軽く、またバックエンド データベースにすべてのモバイル クライアントの同期状態を保存する必要もありません。既に Mobile Services を使用している場合は、下記のチュートリアルを参考にすると簡単にオフライン機能をアプリに追加できます。

この機能を使用する場合、アプリで Core Data が有効化されていて、同時にアプリのデータ オブジェクトと SDK で必要となるシステム テーブルの両方のモデルが定義されている必要があります。アプリの初期化ロジック (iOS のクイックスタート アプリの QSTodoService.init など) で、Mobile Services のローカル ストアを作成し、同期コンテキストと関連付けます。

 // アプリの Core Data モデルに基づいて Mobile Services のローカル ストアを作成
MSCoreDataStore *store = [[MSCoreDataStore alloc] initWithManagedObjectContext:context]; 

// ストアを同期コンテキストと関連付ける
self.client.syncContext = 
    [[MSSyncContext alloc] initWithDelegate:nil
                                 dataSource:store 
                                   callback:nil]; 
        
// TodoItem テーブルが動作するように MSSyncTable インスタンスを作成
self.syncTable = [_client syncTableWithName:@"TodoItem"];

これで、アプリで CRUD 処理を実行する際には必ず (MSTable ではなく) MSSyncTable インスタンスが使用されるようになります。データは Read 処理でローカル ストレージから取得され、Create、Update、Delete の各処理でサーバーに送信されるキューに登録されます。キュー内の変更の送信には pushWithCompletion メソッドが使用されます。これは同期コンテキストに基づくメソッドで、すべての変更内容を順番に再実行します。

 [self.client.syncContext pushWithCompletion:^(NSError *error) { ... } ]

サーバーから新しい変更を取得する際は pullWithQuery メソッドが使用されます。

 [self.syncTable pullWithQuery:query 
                      queryId:@"allTodoItems" 
                   completion:^(NSError *error) { ... } ]

プル処理時に同期テーブルに保留中の変更が存在する場合、SDK はまずすべての変更をプッシュします。差分同期を有効にする場合は queryID パラメーターを使用します。queryID とはプログラム内のクエリに対して一意な記述的文字列で、最後に実行されたプル処理から最終更新日時のタイムスタンプを保存するために SDK によって内部的に使用されます。後続のプル処理では、このタイムスタンプ以降のレコードのみが取得されます。

また、pullWithQuery メソッドでは、特定のデータ サブセットをデバイスに保存するように指定できます。クイックスタートの例では簡単なデータ モデルが使用されているため、すべての TodoItem のアイテムが取得されています。しかし、TodoItem のアイテムの重要度を表すフィールドが追加された場合、アプリは適切なクエリを使用して重要度が高または中のアイテムのみをプルすることができます。ローカル ストアでは Core Data を使用しているので、NSFetchedResultsController を使用すると、キーと値の監視を利用してビュー コントローラーを統合することが可能です。iOS のクイックスタートでは、それを実現した例が示されています。その例では、Core Data が管理するオブジェクトのコンテキストにテーブル ビューを接続しています。iOS およびその他のプラットフォームでオフライン同期機能を使用する場合の詳細については、下記の関連資料も参照してください。