Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/ /

将设备同步添加到应用程序 - Swift SDK

在此页面上

  • 先决条件
  • 将 Device Sync 添加到客户端应用程序
  • 连接到Atlas App Services后端
  • 验证用户身份
  • 打开同步 Realm
  • 使用 Realm

提示

另请参阅:

本页包含有关如何将 Device Sync 添加到应用程序的信息。 如果您正在寻找有关Device Sync是什么及其工作原理的信息,请参阅: Atlas App Services :同步数据。

从客户端访问权限同步域之前,您必须在Atlas App Services用户界面中启用同步。 在此进程,您必须可查询字段与模式中的字段相匹配的可查询字段。 您还可以为应用用户定义读取和写入权限

在此示例中,我们的模型包含一个 ownerId字段,该字段映射到 Flexible Sync 用户的user.id

class Todo: Object {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name: String = ""
@Persisted var ownerId: String
@Persisted var status: String = ""
convenience init(name: String, ownerId: String) {
self.init()
self.name = name
self.ownerId = ownerId
}
}
1

传递应用的 App ID ,您可以在Atlas App Services用户界面中找到该 ID。

let app = App(id: FLEX_SYNC_APP_ID) // Replace FLEX_SYNC_APP_ID with your Atlas App ID
2

在客户端项目中对用户进行身份验证。 在这里,我们将使用匿名身份验证。

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
}
3

将域作为同步域打开。 您可以指定同步域是否应在打开之前下载数据。 在这里,我们使用了Flexible Sync 配置,并指定 SDK 应始终在打开域之前下载最新的更新。 我们使用初始订阅来启动域 。 我们还指定了要包含在该域中的对象类型。

提示

如果您的应用会在 async/await 上下文中访问 Realm,请使用 @MainActor 来标记此代码,从而避免出现与线程相关的崩溃。

@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 的语法相同。 当您使用本地数据时,后台线程可以高效地集成、上传和下载变更集。

以下代码创建一个新的Task对象并将其写入 Realm:

@MainActor
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 而不是每次更改来提高同步性能。

后退

同步数据