Docs 菜单

Docs 主页开发应用程序Atlas Device SDKs

快速入门 - Swift SDK

在此页面上

  • 导入 Realm
  • 定义对象模型
  • 打开 Realm
  • 创建、读取、更新和删除对象
  • 注意更改
  • 添加 Device Sync(可选)
  • 先决条件
  • 初始化 App Services
  • 验证用户身份
  • 打开 Realm

本快速入门演示了如何将 Realm 与 Realm Swift SDK 结合使用。在开始之前,请确保您已安装 Swift SDK。

提示

另请参阅:

如果您的应用使用 SwiftUI,请查看 SwiftUI 快速入门。

在任何使用 Realm 的 Swift 文件顶部附近,添加以下导入语句:

import RealmSwift

对于仅限本地的 Realm,可以直接在代码中定义对象模型。在本快速入门中,您可以删除 ownerId,除非您想添加可选的 Device Sync。

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

在仅限本地的 Realm 中,打开 Realm 的最简单选项是使用不带配置参数的默认 Realm:

// Open the local-only default realm
let realm = try! Realm()

您还可以指定 Realm.Configuration 参数,以在特定的文件 URL、内存中或类的子集上打开域。

有关更多信息,请参阅:配置和打开 Realm。

打开 Realm 后,您可以在写事务区块中修改它及其对象

要创建新的 Todo 对象,请实例化 Todo 类并将其添加到写入区块中的 Realm:

let todo = Todo(name: "Do laundry", ownerId: user.id)
try! realm.write {
realm.add(todo)
}

您可以检索 Realm 中所有待办事项的实时集合

// Get all todos in the realm
let todos = realm.objects(Todo.self)

您还可以使用以下位置过滤该集合:

let todosInProgress = todos.where {
$0.status == "InProgress"
}
print("A list of all todos in progress: \(todosInProgress)")

要修改的待办事项,则在写事务区块中更新其属性:

// All modifications to a realm must happen in a write block.
let todoToUpdate = todos[0]
try! realm.write {
todoToUpdate.status = "InProgress"
}

最后,您可以删除待办事项:

// All modifications to a realm must happen in a write block.
let todoToDelete = todos[0]
try! realm.write {
// Delete the Todo.
realm.delete(todoToDelete)
}

可以使用 observe 方法观察 realm、集合或对象的更改

// Retain notificationToken as long as you want to observe
let notificationToken = todos.observe { (changes) in
switch changes {
case .initial: break
// Results are now populated and can be accessed without blocking the UI
case .update(_, let deletions, let insertions, let modifications):
// Query results have changed.
print("Deleted indices: ", deletions)
print("Inserted indices: ", insertions)
print("Modified modifications: ", modifications)
case .error(let error):
// An error occurred while opening the Realm file on the background worker thread
fatalError("\(error)")
}
}

只要您想继续观察,请务必保留 observe 返回的通知令牌。观察结束后,使令牌失效以释放资源:

// Invalidate notification tokens when done observing
notificationToken.invalidate()

如果您要跨设备同步 Realm 数据,则可以设置 Atlas App Services 应用程序并启用 Device Sync。有关 App Services 的详情,请参阅:App Services - Swift SDK

同步 Realm 数据之前,您必须:

要使用身份验证和同步等 App Services 功能,请使用您的App ID 访问 App Services 应用。您可在 App Services 用户界面中找到您的 App ID

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

在此快速入门中,您将使用匿名身份验证登录用户,而不需要他们提供任何身份信息。验证用户身份后,可以为该用户打开域。

do {
let user = try await app.login(credentials: Credentials.anonymous)
print("Successfully logged in user: \(user)")
await openSyncedRealm(user: user)
} catch {
print("Error logging in: \(error.localizedDescription)")
}

Realm Swift SDK 提供了许多其他方法来进行身份验证、注册和链接用户。有关其他身份验证提供者,请参阅:对用户进行身份验证 - Swift SDK

启用 Device Sync 并对用户进行身份验证后,您可以创建配置对象并打开域。然后,您可以添加“Flexible Sync”订阅,确定该域可以读写哪些数据。

您有带订阅的 Realm 后,这个示例将该 Realm 和用户到另一个函数,您可以在该函数中使用该 Realm。

提示

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

// Opening a realm and accessing it must be done from the same thread.
// Marking this function as `@MainActor` avoids threading-related issues.
@MainActor
func openSyncedRealm(user: User) async {
do {
var config = user.flexibleSyncConfiguration()
// 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)
// You must add at least one subscription to read and write from a Flexible Sync realm
let subscriptions = realm.subscriptions
try await subscriptions.update {
subscriptions.append(
QuerySubscription<Todo> {
$0.ownerId == user.id
})
}
await useRealm(realm: realm, user: user)
} catch {
print("Error opening realm: \(error.localizedDescription)")
}
}

在同步 Realm 上读取写入监控变更的语法与对上述非同步 Realm 的语法相同。当您使用本地数据时,后台线程可以高效地集成、上传和下载变更集。

订阅集的每个写入事务都会产生性能成本。如果需要在会话期间对 Realm 对象进行多次更新,请考虑将编辑的对象保留在内存中,直到所有更改完成。这通过仅将完整且更新的对象写入 Realm 而不是每次更改来提高同步性能。

← 安装适用于 iOS、macOS、tvOS 和 watchOS 的 SDK