Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

SwiftUI を使用してバックグラウンドでデータを同期する - Swift SDK

項目一覧

  • Overview
  • アプリのバックグラウンド モードを有効にする
  • バックグラウンド モード機能を追加する
  • バックグラウンド モードを選択します
  • info.plist を更新する
  • バックグラウンド タスクのスケジュール
  • バックグラウンド タスクの作成
  • タスクのバックグラウンドをテストする
  • アプリを実行するためのデバイスの構成
  • ブレークポイントを設定する
  • アプリを実行する
  • Atlas でのデータの追加または変更
  • LDDB でのバックグラウンド タスクの呼び出し
  • デバイスでプレーンモードをオンにする
  • アプリを開く

SwiftUI BackupTask{ を使用できます アプリがバックグラウンドで稼働しているときに 同期された邦土を更新するにはこの例では、 iOSアプリでバックグラウンド同期を構成および実行する方法を説明します。

SwiftUI Device Sync テンプレート アプリを使用して、このページの例に従うことができます。 テンプレート アプリの独自のコピーを取得するには、DeviceDevice SyncSwiftUI SyncSwiftUIDevice SyncGo 確認し、 4} セクションとPrerequisites Start with the Templateセクションを確認してください。

アプリのバックグラウンド タスクを有効にするには、次の手順に従います。

1

アプリのターゲットを選択し、Signing & Capabilities タブにGoし、+ Capability をクリックして機能を追加します。

アプリ ターゲットが選択され、「署名と機能」タブが開き、機能を追加するための矢印が指している Xcode のスクリーンショット。
クリックして拡大します

「バックグラウンド」を検索し、[ Background Modes ] を選択します。

2

これでSigning & CapabilitiesタブにBackground Modesセクションが表示されます。 このセクションを展開し、チェックボックスをクリックしてBackground fetchBackground processingを有効にします。

3

GoプロジェクトのInfo.plistPermitted background task scheduler identifiers し、{1 の新しい行を追加します。未加工のキーと値を表示している場合、キーはBGTaskSchedulerPermittedIdentifiersです。 このフィールドは配列です。 バックグラウンド タスク識別子用に新しい項目を追加します。 新しいアイテムの 値を、バックグラウンド タスクの識別子として使用する string に設定します。 たとえばrefreshTodoRealm

アプリのバックグラウンド プロセスを有効にした後、アプリへのコードの追加を開始して、バックグラウンド タスクをスケジュールおよび実行できます。 まず、このコードを記述するファイルにBackgroundTasksをインポートします。

import SwiftUI
import RealmSwift
import BackgroundTasks

スケジュールされたバックグラウンド タスクを追加できるようになりました。 テンプレート アプリを使用してアプリを実行している場合は、 @mainビューをアップデートできます。

@main
struct realmSwiftUIApp: SwiftUI.App {
@Environment(\.scenePhase) private var phase
var body: some Scene {
WindowGroup {
ContentView(app: realmApp)
}
.onChange(of: phase) { newPhase in
switch newPhase {
case .background: scheduleAppRefresh()
default: break
}
}
}

scenePhase : @Environment(\.scenePhase) private var phaseへの変更を保存するための環境変数を追加できます。

次に、アプリがバックグラウンドになるときにscheduleAppRefresh()関数を呼び出す.onChange(of: phase)ブロックを追加できます。

scheduleAppRefresh()関数を作成します。

func scheduleAppRefresh() {
let backgroundTask = BGAppRefreshTaskRequest(identifier: "refreshTodoRealm")
backgroundTask.earliestBeginDate = .now.addingTimeInterval(10)
try? BGTaskScheduler.shared.submit(backgroundTask)
}

これにより、バックグラウンド モードを有効にしたときに 上記で Index.plist に追加した識別子を持つバックグラウンド タスクが実行されるようスケジュールされます。 この例では、識別子refreshTodoRealmがこのタスクを参照しています。

バックグラウンド タスクをスケジュールしたので、同期された Realm を更新するために実行されるバックグラウンド タスクを作成する必要があります。

テンプレート アプリで次のアプリを使用している場合は、 .onChange(of: phase)の後にこのbackgroundTask@mainビューに追加できます。

.onChange(of: phase) { newPhase in
switch newPhase {
case .background: scheduleAppRefresh()
default: break
}
}
.backgroundTask(.appRefresh("refreshTodoRealm")) {
guard let user = realmApp.currentUser else {
return
}
let config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
if let foundSubscription = subs.first(named: "user_tasks") {
foundSubscription.updateQuery(toType: Item.self, where: {
$0.owner_id == user.id
})
} else {
subs.append(QuerySubscription<Item>(name: "user_tasks") {
$0.owner_id == user.id
})
}
}, rerunOnOpen: true)
await refreshSyncedRealm(config: config)
}

このバックグラウンド タスクは、まずアプリにログインしているユーザーがあることを確認します。 その場合、 .FlexibleSyncConfigurationが設定されます アプリがRealmを同期するために使用できるサブスクライブ。

これは、テンプレート アプリのContentViewで使用されるのと同じ構成です。 ただし、ここで使用するには、ビュー階層のはるかに上にある へのアクセスが必要です。 これを、ユーザーをパラメーターとして受け取り、 Realm.config を返すいずれのビューからでも呼び出せる関数にリファクタリングできます。

最後に、このタスクは Realm を実際に同期する関数の結果を待ちます。 この関数を追加します。

func refreshSyncedRealm(config: Realm.Configuration) async {
do {
try await Realm(configuration: config, downloadBeforeOpen: .always)
} catch {
print("Error opening the Synced realm: \(error.localizedDescription)")
}
}

この同期された Realm を開き、 downloadBeforeOpenパラメーターを使用してアップデートをダウンロードすることを指定すると、新しいデータが Realm にバックグラウンドでロードされます。 その後アプリが再度開くと、デバイス上の更新されたデータがすでに存在しています。

重要

このバックグラウンド タスクで、Realm に直接書き込まないでください。 Realm のスレッドセーフなアーキテクチャにより、スレッド関連の問題が発生する可能性があります。

バックグラウンド タスクをスケジュールするときは、システムがタスクを実行できる最速の時間を設定します。 ただし、オペレーティング システムは他の多くの考慮事項を考慮し、予定されたearliestBeginDateの後にバックグラウンド タスクの実行が遅れる可能性があります。 デバイスがバックグラウンド タスクを実行するのを待ってから、意図した結果を実行することを確認する代わりに、ブレークポイントを設定し、LDDB を使用してタスクを呼び出すことができます。

1

バックグラウンド タスクがバックグラウンドで同期された Realm を更新していることをテストするには、少なくとも iOS 16を実行している物理デバイスが必要です。 デバイスは 開発者モード で実行するように構成されている必要があります 。Untrusted Developer 通知を受け取った場合は、SettingsGeneralVPN & Device Management にGoします。 ここで、開発しているアプリを実行することを確認できます。

デバイス上でアプリを正常に実行できたら、バックグラウンドのタスクをテストできます。

2

まず、 scheduleAppRefresh()関数にブレークポイントを設定します。 BGTaskSchedulerにタスクを送信する行のにブレークポイントを設定します。 この例では、 print行を追加し、出力行にブレークポイントを設定できます。

func scheduleAppRefresh() {
let backgroundTask = BGAppRefreshTaskRequest(identifier: "refreshTodoRealm")
backgroundTask.earliestBeginDate = .now.addingTimeInterval(10)
try? BGTaskScheduler.shared.submit(backgroundTask)
print("Successfully scheduled a background task") // Set a breakpoint here
}
3

ここで、接続されたデバイスでアプリを実行します。 アプリ内でアカウントを作成またはサインインします。 SwiftUI テンプレート アプリを使用している場合は、いくつかのアイテムを作成します。 Atlas App Services アプリにリンクされたItemコレクションにアイテムが同期されているはずです。

次に、Xcode でアプリを実行したままに、アプリをデバイスのバックグラウンドに送信します。 コンソールに「バックグラウンド タスクが正常にスケジュールされました」と表示され、その後 LDDB プロンプトが表示されます。

4

アプリがバックグラウンドではありますが、Xcode で実行中のままである間に、デバイスに同期する必要がある新しいドキュメントを関連する Atlas コレクションに挿入します。 あるいは、デバイスから作成した既存のドキュメントの 値を変更します。 バックグラウンド タスクを正常に実行すると、このデータがバックグラウンド プロセスからデバイスに同期されたことが表示されます。

SwiftUI テンプレート アプリを使用している場合は、Atlas クラスターのItemコレクションから関連するドキュメントを見つけることができます。 Atlas でドキュメントを追加または変更する方法の詳細については、「 MongoDB Atlas: ドキュメントの作成、表示、更新、削除 」を参照してください。

5

LDDB でバックグラウンド タスクを手動で実行するには、次のコマンドを使用します。

e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"refreshTodoRealm"]

バックグラウンド タスクに別の識別子を使用した場合は、 refreshTodoRealmをタスクの識別子に置き換えます。 これにより、タスクはすぐに実行を開始できます。

成功した場合は、次のようなものが表示されます。

2022-11-11 15:09:10.403242-0500 App[1268:196548] Simulating launch for task with identifier refreshTodoRealm
2022-11-11 15:09:16.530201-0500 App[1268:196811] Starting simulated task

タスクを開始した後、Xcode デバッグ パネルの [ Continue program execution ] ボタンを使用してアプリの実行を再開します。

6

バックグラウンド タスクが完了するのを待った後、アプリを再度開く前に、デバイスで航空会社モードをオンにします。 Wire がオフになっていることを確認します。 これにより、アプリを再度開いても、新しい同期が開始されることはなく、デバイス上の Realm に現在含まれている値のみが表示されます。

7

デバイス上でアプリを開きます。 Atlas で変更した更新されたデータが表示されます。

バックグラウンド タスクを介して更新が行われたことを確認するには、ネットワークが正常に無効になっていることを確認します。

アプリを使用して新しいタスクを作成します。 アプリに タスクが表示されますが、Atlas には同期されないはずです。 あるいは、Atlas でデータを作成または変更することもできますが、それがデバイスに反映されないようにしてください。

これは、ネットワークが正常に無効化され、表示される更新されたデータがバックグラウンド タスクを介して送信されたことを示します。

戻る

同期エラーの処理