はじめに
ここでは、Couchbaseが公開しているCouchbasae Mobileチュートリアルから、バックグラウンドフェッチに関するものを紹介します。
Couchbase Mobileについては、以下参照ください。
Couchbase Mobileは、NoSQL組み込みデータベースCouchbase Lite、およびCouchbase ServerとCouchbase Liteとのデータ同期を担うSync Gatewayからなります。
Couchbase Serverについては、次の拙著を紹介させていただきます。
チュートリアルについて
以下で、プロジェクトが公開されています。
本稿の内容は、下記チュートリアルに基づきます。
本稿では、バックグラウンドでの同期に関する内容の紹介にフォーカスしています。実行環境・手順などの詳細は、上記ご確認ください。
バックグラウンドでのCouchbase Serverとの同期
iOS Background App Refresh(バックグラウンドアプリ更新)とは
iOSはいくつかのバックグラウンドモデルをサポートしています。そのオプションの1つに、Background App Refresh(バックグラウンドアプリ更新)があります。Background App Refreshを使用すると、アプリをバックグラウンドで定期的に実行して、コンテンツを更新できるようになります。
アプリを起動して実行するタイミングは、iOSによって決定されます。通常、時間の経過とともにアプリの使用状況が学習されます。
言い換えると、必ずしもアプリがバックグラウンドで実行される機会があるという保証はありません。機会が与えられた場合でも、アプリの実行時間には限りがあります(30秒)。
有効化設定
Background App Refreshを有効化するには、プロジェクトの[Capabilities 機能]タブを開きます。[バックグラウンドモード Background Modes]セクションで[バックグラウンドフェッチ Background fetch]が有効にします。
チュートリアルのUserProfileDemo.xcodeprojファイルを利用する場合は、あらかじめ設定されています。上記の設定を確認します。
実行周期設定
AppDelegate.swiftファイルを開き、application:didFinishLaunchingWithOptions()
関数を確認します。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
self.loadLoginViewController()
UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
return true
}
ここで、アプリを起動する周期を指定しています。システムでサポートされている最小のフェッチ間隔であるUIApplicationBackgroundFetchIntervalMinimum
の値を使用しています。
コールバックの実装
AppDelegate.swiftファイルを開き、application:performFetchWithCompletionHandler()
関数を確認します。このコールバック関数は、システムによってアプリがバックグラウンドで起動される際に呼び出されます。
// Support for background fetch
func application( _ application: UIApplication,
performFetchWithCompletionHandler
completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print(#function)
// Do a one shot replication
self.cbMgr.startOneShotPullReplicationForCurrentUser { (status) in
completionHandler(.newData)
}
}
ここでは、Sync Gatewayでワンショットプルレプリケーションを実行しています。アプリが起動されるたびに、Sync Gatewayで保留中のすべての変更が同期されます
ワンショットレプリケーションの実装
ワンショットレプリケーション用のアプリのセットアップは、同期チュートリアルで説明した連続レプリケーションと非常によく似ています。
DatabaseManager.swiftのstartOneShotPullReplicationForCurrentUser()
関数で実装されてます。
func startOneShotPullReplicationForCurrentUser(completionHandler:@escaping(_ doneStatus:Bool)->Void) {
レプリケーターの構成は、以下のようになっています。
let dbUrl = remoteUrl.appendingPathComponent(kDBName)
let config = ReplicatorConfiguration.init(database: db, target: URLEndpoint.init(url:dbUrl))
config.continuous = false ①
config.replicatorType = .pull ②
config.authenticator = BasicAuthenticator(username: user, password: password)
- ①「continuous」モードが「false」に設定されており、これがワンショットレプリケーションであることを示しています。ワンショットモードでは、保留中のすべての変更が同期されると、レプリケーターはアイドル状態になります
- ② 「replicationType」は「pull」に設定されており、アプリがバックグラウンドでリモートからの変更をプルすることを示しています。
シミュレーターによる確認
Sync Gatewayで行われた変更がバックグラウンドでiOSアプリによってどのように取得されるかを確認します。
バックグラウンドフェッチをシミュレートするためには、xcodeデバッガーを使用します。アプリは、xcodeデバッガーが接続されたシミュレーターで実行されている必要があります。
シミュレーターのアプリをバックグラウンドにプッシュします。通常、Shift+Cmd+Hの組み合わせで実行できます。
xcodeのデバッグコンソールログをクリアします。これにより、アプリがバックグラウンドで起動されたときに何が起こっているかを簡単に識別できるようになります。
コマンドターミナルを開き、次のcurlコマンドを発行して、GET Document RESTAPIを介してSync Gatewayでユーザープロファイルドキュメントを取得します
curl -X GET \
http://localhost:4985/userprofile/user::demo@example.com \
-H 'Accept: application/json' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json'
応答は次のようになります。実際の内容は、アプリ上で作成されたユーザープロファイルによって異なります。
{
"_attachments": {
"blob_/image": {
"content_type": "image/jpeg",
"digest": "sha1-9OHO0QIk+kREiOaoMlrEg/jU4zU=",
"length": 15110,
"revpos": 1,
"stub": true
}
},
"_id": "user::demo@example.com",
"_rev": "1-0b9e3efa5ec1b1596564c4db34ba28d4e618f9c5",
"address": "",
"email": "demo@example.com",
"image": {
"@type": "blob",
"content_type": "image/jpeg",
"digest": "sha1-9OHO0QIk+kREiOaoMlrEg/jU4zU=",
"length": 15110
},
"name": "",
"type": "user"
}
上記のプロファイルの一部を変更するために、次のコマンドを発行して、PUT Document REST APIを介してSync Gatewayのユーザープロファイルドキュメントを更新します。
curl -X PUT \
'http://localhost:4985/userprofile/user::demo@example.com?rev=1-0b9e3efa5ec1b1596564c4db34ba28d4e618f9c5' \
-H 'Accept: application/json' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-d '{
"address": "101 Main Street",
"email": "demo@example.com",
"image": {
"@type": "blob",
"content_type": "image/jpeg",
"digest": "sha1-S8asPSgzA+F+fp8/2DdIy4K+0U8=",
"length": 14989
},
"name": "priya Rajagopal",
"type": "user",
"university": "British Institute in Paris, University of London"
}'
iOSアプリをバックグラウンドで起動します。
Xcodeの[デバッグ Debug]メニューから[バックグラウンドフェッチのシミュレーション Simulate Background Fetach]を選択します。
コンソールログを観察します。アプリがSync Gatewayから最新の変更をプルしたことを示す一連のメッセージが表示されます
フォアグラウンドでアプリを起動します。バックグラウンドで同期されたユーザープロファイルドキュメントが表示されます。
関連情報