アプリに Device Sync を追加する - Swift SDK
Tip
以下も参照してください。
このページには、Device Sync をアプリに追加する方法に関する情報が記載されています。 Device Sync の仕組みとその仕組みについて詳しくは、「 App Services: データの同期 」を参照してください。
前提条件
クライアントから同期された Realm にアクセスする前に、Atlas App Services UI で同期を有効にする必要があります。 このプロセスでは、スキーマ内のフィールドと一致するクエリ可能なフィールドを定義する必要があります。 アプリ ユーザーの読み取りおよび書込み権限も定義します。
この例では、モデルには Flexible Sync ユーザーのuser.id
にマップする ownerId
フィールドが含まれています。
class Todo: Object { true) var _id: ObjectId (primaryKey: var name: String = "" var ownerId: String var status: String = "" convenience init(name: String, ownerId: String) { self.init() self.name = name self.ownerId = ownerId } }
クライアント アプリケーションへの Device Sync の追加
App Services バックエンドへの接続
App Services UI で確認できるアプリのアプリケーション ID を渡します。
let app = App(id: FLEX_SYNC_APP_ID) // Replace FLEX_SYNC_APP_ID with your Atlas App ID
ユーザーの認証
クライアント プロジェクトでユーザーを認証します。 ここでは、匿名認証を使用します。
func login() async throws -> User { // Authenticate with the instance of the app that points // to your backend. Here, we're using anonymous login. let user = try await app.login(credentials: Credentials.anonymous) print("Successfully logged in user: \(user)") return user }
同期された Realm を開く
同期された Realm として Realm を開きます。 同期された Realm が開く前にデータをダウンロードするかどうかを指定できます。 ここでは、 Flexible Sync 構成を使用し、Realm を開く前に SDK が常に最新の更新をダウンロードする必要があることを指定します。 初期サブスクリプション で Realm をブートストラップします。 この Realm に含めるオブジェクトタイプも指定します。
Tip
アプリがasync/await
コンテキストで Realm にアクセスする場合は、スレッド関連のクラッシュを回避するためにコードを@MainActor
でマークします。
func openSyncedRealm(user: User) async { do { var config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in subs.append( QuerySubscription<Todo> { $0.ownerId == user.id }) }) // Pass object types to the Flexible Sync configuration // as a temporary workaround for not being able to add a // complete schema for a Flexible Sync app. config.objectTypes = [Todo.self] let realm = try await Realm(configuration: config, downloadBeforeOpen: .always) useRealm(realm, user) } catch { print("Error opening realm: \(error.localizedDescription)") } }
Realm の使用
同期された Realm で を読み取り、書込み、変更を監視する構文は、同期されていない Realm の構文と同じです。 ローカル データを操作している間に、バックグラウンド スレッドが変更セットを効率的に統合、アップロード、ダウンロードします。
次のコードでは、新しいTask
オブジェクトを作成し、それを Realm に書込みます。
func useRealm(_ realm: Realm, _ user: User) { // Add some tasks let todo = Todo(name: "Do laundry", ownerId: user.id) try! realm.write { realm.add(todo) } }
重要
同期を使用する場合は、メイン スレッドでの書込みを避ける
Realm がバックグラウンド スレッドで同期統合を実行するということを意味するため、メイン スレッドで Realm に書き込むと、バックグラウンドの同期スレッドが書込みトランザクションを完了するのを待機するため、UI がハングする可能性が低くなる可能性があります。 したがって、 Device Sync を使用するときにメイン スレッドに書き込まないのがベストプラクティスです。
サブスクリプションセットのすべての書込みトランザクション (write transaction) にはパフォーマンス コストがかかります。 セッション中に Realm オブジェクトを複数更新する必要がある場合は、すべての変更が完了するまで編集されたオブジェクトをメモリ内に保持することを検討してください。 これにより、すべての変更ではなく、完全で更新されたオブジェクトのみが Realm に書き込まれるため、同期のパフォーマンスが向上します。