Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

同期セッションの管理 - Swift SDK

項目一覧

  • 同期接続の動作
  • ネットワーク接続の確認
  • 同期セッションの一時停止または再開
  • 同期セッションを一時停止するタイミング
  • アップロードまたはダウンロードする変更を待機する
  • 同期セッションのアップロードとダウンロードの進行状況を確認
  • すべての同期セッションの手動再接続

同期された Realm を起動すると、その Realm の SyncSessionが開始されます。 Realm Swift SDK には、同期セッションを手動で一時停止および再開する方法が用意されています。

バージョン 10.41.0 の新機能

Realm Swift SDK バージョン 10.41.0 以降では、App Services はデフォルトで、開かれたすべての同期済み Realm に対してサーバーへの単一の接続を共有します。 これは、同期された Realm を複数開くとサーバーへの追加の接続が開かれていた以前のバージョンからの変更です。 サーバーへの接続は SyncSessionとは独立しており、App Services ユーザーに基づいています。

この動作は、アプリ クライアントの構成から変更できます。

Tip

Realm のオフラインファーストの設計により、現在のネットワーク接続状態を確認する必要は通常ありません。 つまり、アプリが接続状態の指標として を呼び出す場合は、 connectionStateプロパティが使用できます。

接続状態を確認するには、同期された Realm の RRMSyncSession インスタンスのconnectionStateプロパティを直接読み取ります。

このプロパティは KVE に準拠しています 、KVE を使用して変更を監視できます。次の例は、オブザーバークラスを実装する方法を示しています。

@interface MySyncSessionObserver: NSObject
@end
@implementation MySyncSessionObserver
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (![object isKindOfClass:RLMSyncSession.class]) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
if (![keyPath isEqualToString:@"connectionState"]) {
// Not interested in observing this keypath
return;
}
RLMSyncSession *syncSession = (RLMSyncSession *)object;
RLMSyncConnectionState connectionState = [syncSession connectionState];
switch (connectionState) {
case RLMSyncConnectionStateConnecting:
NSLog(@"Connecting...");
break;
case RLMSyncConnectionStateConnected:
NSLog(@"Connected");
break;
case RLMSyncConnectionStateDisconnected:
NSLog(@"Disconnected");
break;
}
}
@end

次に、オプティマイザー インスタンスを RMSyncSession オブジェクトにアタッチできます。 終了したら必ずオブジェクトを削除してください。

// Observe connectionState for changes using KVO
MySyncSessionObserver *observer = [[MySyncSessionObserver alloc] init];
[syncSession addObserver:observer
forKeyPath:@"connectionState"
options:NSKeyValueObservingOptionInitial
context:nil];
// Later, when done...
[syncSession removeObserver:observer
forKeyPath:@"connectionState"
context:nil];

接続状態を確認するには、同期された Realm の SyncSession インスタンスのconnectionStateプロパティを直接読み取ります。

このプロパティは KVE に準拠しています 、したがって、KVM または 組み合わせ を使用して変更を監視できます。

// Observe connectionState for changes using KVO
let observer = syncSession.observe(\.connectionState, options: [.initial]) { (syncSession, change) in
switch syncSession.connectionState {
case .connecting:
print("Connecting...")
case .connected:
print("Connected")
case .disconnected:
print("Disconnected")
default:
break
}
}
// Observe using Combine
let cancellable = syncSession.publisher(for: \.connectionState)
.sink { connectionState in
switch connectionState {
case .connecting:
print("Connecting...")
case .connected:
print("Connected")
case .disconnected:
print("Disconnected")
default:
break
}
}

Realm で同期セッションを一時停止および再開できます。 同期セッションを一時停止すると、その Realm の同期セッションのみが一時停止されます。 オープンしている Realm が複数ある場合、一時停止は他の Realm の同期セッションに影響を与えません。

同期された Realm のRRMSyncSessionインスタンスを使用して、同期セッションを一時停止または再開できます。

RLMRealm *syncedRealm = [RLMRealm realmWithConfiguration:configuration error:nil];
RLMSyncSession *syncSession = [syncedRealm syncSession];
// Suspend synchronization
[syncSession suspend];
// Later, resume synchronization
[syncSession resume];

同期された Realm のSyncSessionインスタンスを使用して、同期セッションを一時停止または再開できます。

let syncSession = syncedRealm.syncSession!
// Suspend synchronization
syncSession.suspend()
// Later, resume synchronization
syncSession.resume()

ほとんどのアプリケーションでは、同期セッションを手動で一時停止して再開する必要はありません。 ただし、同期セッションを一時停止または一時停止する必要がある状況もいくつかあります。

  • ユーザーが特定のアクションを実行した後にのみ同期したい場合

  • 特定の時間のみ同期したい場合

  • ネットワーク接続が不十分な場合、同期は試行しないでください

  • 同期セッションを明示的に接続するよう強制したい場合

ネットワーク接続が不十分な場合、ネットワーク接続を確立しようとすると、ユーザーのデバイスのバックアップが枯渇する可能性があります。

同期セッションを明示的に接続するよう 強制する 場合は、一時的にオフラインであることがほとんどです。 同期クライアントは接続を試み、失敗すると指数バックオフになります。 長時間オフラインになると、クライアントがすぐに再接続されないことがあります。 同期セッションを一時停止および再開すると、接続が明示的に強制されます。

同期セッションを一時停止するときは、次の点に注意してください。

  • クライアントがクライアントの最大オフライン時間よりも長時間オフラインになると、クライアントは同期を再開できなくなり、クライアント リセットを実行する必要があります。

  • 同期セッションを一時停止すると、両方の方向で一時停止されます。 アプリがデバイスで行った変更はバックエンド同期されず、バックエンドまたは他のデバイス上のデータに対する変更はデバイスに同期されません。 アップロードのみを一時停止したり、ダウンロードのみを一時停止したりする方法はありません。

  • クライアントがバックエンドとの同期を永続的に停止する場合は、同期セッションを一時停止しないでください。 同期を永続的に停止するには、同期された Realm の内容を同期されていない Realm にコピーし、クライアントで同期されていない Realm を使用します。

無期限の同期を停止するために、同期を一時停止しないでください。 この機能は、これらのユースケース向けに設計またはテストされていません。 この方法で使用すると、さまざまな問題が発生する可能性があります。

バージョン 10.45.0 の新機能

すべての変更が同期された Realm からアップロードまたはダウンロードされるまで待機するには、 realm.syncSession?.wait(: ) を呼び出します。

このメソッドは、アップロード進行状況を追跡するか、ダウンロード 進行状況を追跡するかを指定するためにProgressDirection引数を受け取ります。

これらのメソッドは、Swift の async/await 構文、または コールバック構文で使用できます。 コールバック バージョン、 Realm.syncSession?.wait(for:queue:lock:)では、コールバックをディスパッチするためのキューと、待機が完了したときに呼び出すブロックが利用できます。

// Wait to download all pending changes from Atlas
try await realm.syncSession?.wait(for: .download)
// Add data locally
try realm.write {
realm.create(Task.self, value: [
"taskName": "Review proposal",
"assignee": "Emma",
"completed": false,
"progressMinutes": 0,
"dueDate": date
])
}
// Wait for local changes to be uploaded to Atlas
try await realm.syncSession?.wait(for: .upload)
// Wait to download all pending changes from Atlas
realm.syncSession?.wait(for: .download, block: { _ in
// You can provide a block to execute
// after waiting for download to complete
})
// Add data locally
do {
try realm.write {
realm.create(Task.self, value: [
"taskName": "Review proposal",
"assignee": "Emma",
"completed": false,
"progressMinutes": 0,
"dueDate": date
])
}
} catch {
print("There was an error writing to realm: \(error.localizedDescription)")
}
// Wait for local changes to be uploaded to Atlas
realm.syncSession?.wait(for: .upload, block: { _ in
// You can provide a block to execute after
// waiting for upload to complete
})

バージョン10.50.0での変更: transferredBytestransferrableBytesは非推奨になり、代わりにprogressEstimateが採用されるようになりました

特定のアップロードまたはダウンロードの方向と作業範囲に対してprogressEstimateを提供するトークンを登録することで、アップロードとダウンロードの進行状況を確認できます。 ProgressModeを設定して作業範囲を決定できます。無期限に監視するか、現在の作業項目が完了した後にブロックを登録解除します。

トークンによって提供されるprogressEstimate値は、 0.0から1.0までの値の範囲を持つ double です。 1.0で、アップロードまたはダウンロードが完了します。 このprogressEstimateを使用して、進行状況インジケーターや推定データ転送割合を表示できます。

バージョン10.50.0での変更: addProgressNotificationForDirectionは非推奨となり、代わりにaddSyncProgressNotificationForDirectionが採用されました

同期された Realm の RMSyncSession インスタンスの[-addSyncProgressNotificationForDirection:mode:lock:]メソッドを使用して、進行状況通知を追加できます。

このメソッドは、アップロードまたはダウンロードの進行状況の監視を停止するまで保持する必要があるトークンを返します。 トークンをローカル変数に保持している場合、ローカル変数がスコープを超えると監視が停止することに注意してください。

RLMSyncSession *syncSession = [syncedRealm syncSession];
RLMProgressNotificationToken *token = [syncSession
addSyncProgressNotificationForDirection:RLMSyncProgressDirectionUpload
mode:RLMSyncProgressModeForCurrentlyOutstandingWork
block:^(RLMSyncProgress syncProgress) {
NSLog(@"Uploaded %fB", (double)syncProgress.progressEstimate);
}];
// Upload something
[syncedRealm transactionWithBlock:^{
[syncedRealm addObject:[[Task alloc] init]];
}];

同期された Realm の SyncSession インスタンスのaddProgressNotification(for:mode:stream:)メソッドを使用して、進行状況通知を追加できます。

このメソッドは、アップロードまたはダウンロードの進行状況の監視を停止するまで保持する必要があるトークンを返します。 トークンをローカル変数に保持している場合、ローカル変数がスコープを超えると監視が停止することに注意してください。

let syncSession = realm.syncSession!
let token = syncSession.addProgressNotification(
for: .upload, mode: .forCurrentlyOutstandingWork) { (progress) in
let progressEstimate = progress.progressEstimate
let transferPercent = progressEstimate * 100
print("Uploaded (\(transferPercent)%)")
}

バージョン 10.44.0 の新機能

Realm は、デバイスがオフラインの後に接続を回復し、増分バックオフ戦略を使用して再接続を試みることを自動的に検出します。 たとえば、Apple プラットフォームでは、Realm はネットワーク変更通知をリッスンし、受信した後すぐに再接続を自動的にトリガーします。

Swift SDKバージョン 10.44.0 以降では、増分バックオフの期間を待つ代わりに、SyncSession.reconnect() を使用して再接続試行を手動でtriggerすることを選択できます。 これは、ネットワーク条件をより正確に理解し、Realm の自動再接続検出に依存したくない場合に便利です。

let syncSession = realm.syncSession!
// Work with the realm. When you need to force the sync session to reconnect...
syncSession.reconnect()

このメソッドを呼び出すと、SDK はすべての同期セッションに直ちに再接続を試行するように強制します。 これにより、増分バックオフに使用されるすべてのタイマーがリセットされます。

このメソッドを呼び出しても、デバイスが再接続できることは保証されません。 SDK で致命的なエラーが発生した場合、またはデバイスがすでに接続されているか、接続しようとしている場合、このメソッドを呼び出しても効果はありません。

重要

ソケット読み取りタイムアウト期間内に再接続できません

Realmの内部デフォルトのソケット読み取りタイムアウトは 2 分であり、読み取り操作が 2 分以内にデータを受信しない場合はRealmになります。 そのウィンドウ内でSyncSession.reconnect()を呼び出すと、Swift SDK は再接続を試行しませ

戻る

バックグラウンドでのデータの同期