将设备同步添加到应用程序 - Swift SDK
提示
另请参阅:
本页包含有关如何将 Device Sync 添加到应用程序的信息。 如果您正在寻找有关Device Sync是什么及其工作原理的信息,请参阅: Atlas App Services :同步数据。
先决条件
Before you can access a synced realm from the client, you must Enable sync in the Atlas App Services UI. During this process, you must define queryable fields that match fields in your schema. You also define read and write permissions for app users.
在此示例中,我们的模型包含一个 ownerId
字段,该字段映射到 Flexible Sync 用户的user.id
。
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 添加到客户端应用程序
连接到Atlas App Services后端
传递应用的 App ID ,您可以在Atlas App Services用户界面中找到该 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”配置,并指定 SDK 应始终在打开 Realm 之前下载最新的更新。我们使用初始订阅来启动 Realm 。我们还指定了要包含在该 Realm 中的对象类型。
提示
如果您的应用会在 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,则您的用户界面在等待后台同步线程完成写入事务时,很有可能会挂起。 因此,在使用 Device Sync 时,最佳实践是不要在主线程上进行写入。
订阅集的每个写入事务都会产生性能成本。如果需要在会话期间对 Realm 对象进行多次更新,请考虑将编辑的对象保留在内存中,直到所有更改完成。这通过仅将完整且更新的对象写入 Realm 而不是每次更改来提高同步性能。