Docs 菜单
Docs 主页
/ /
Atlas App Services

教程:使用 Swift 用户界面的 Atlas Device Sync for Swift

在此页面上

  • 学习目标
  • 先决条件
  • 从模板开始
  • 探索模板应用
  • 打开应用
  • 探索应用结构
  • 运行应用
  • 检查后端
  • 修改应用程序
  • 添加新属性
  • 向模型添加属性
  • 创建新事项时设置优先级
  • 运行和测试
  • 更改订阅
  • 更新订阅
  • 运行和测试
  • 结论
  • 接下来的步骤

预计完成时间:30 分钟,根据您的 SwiftUI 体验而定

Realm 提供了 Swift SDK,它支持您使用 Swift 或 Objective-C 创建原生 iOS 移动应用。Realm 提供了 Swift SDK,它支持您使用 Swift 或 Objective-C 创建原生 iOS 移动应用。本教程基于名为 swiftui.todo.flex 的 SwiftUI 灵活同步模板应用,该应用演示了待办事项清单应用程序的创建。该应用程序使用户能够:

  • 将他们的电子邮件注册为新用户帐户。

  • 使用电子邮件和密码登录他们的帐户(稍后退出)。

  • 查看、创建、修改和删除自己的任务。

  • 查看所有任务,即使用户不是所有者。

模板应用还提供了一个切换开关,用于模拟处于“离线模式”的设备。此切换开关可以让您在模拟器上模拟没有互联网连接的用户,以快速测试 Device Sync 功能。但是,您可能会在生产应用程序中删除此切换开关。

本教程基于模板应用构建。您可向现有 Item 模型添加一个新的 priority 字段,并更新灵活同步订阅以仅显示优先级范围内的项目。

本教程说明如何根据自己的需要调整模板应用。考虑到模板应用的当前结构,您不一定会进行该更改。

在本教程中,您将学习如何:

  • 使用非重大更改更新 Realm 对象模型。

  • 更新 Device Sync 订阅。

  • 将可查询字段添加到服务器上的 Device Sync 配置中,以更改要同步的数据。

提示

如果您更想开始使用自己的应用程序而不是跟随引导式教程,请查看 Swift 快速入门。 其中包括可复制的代码示例以及设立Atlas App Services后端所需的基本信息。

有关特定于 SwiftUI 的入门体验,请参阅 Realm 和 SwiftUI 快速入门

  • 本教程从“模板应用程序”开始。创建“模板应用程序”需要 Atlas 帐号、API 密钥和 App Services CLI。

    • 如需了解有关创建 Atlas 帐户的更多信息,请参阅 Atlas 入门文档。在本教程中,您需要一个带有免费层级集群的 Atlas 帐户。

    • 您还需要一个用于登录的 MongoDB Cloud 账户的 Atlas API 密钥。您必须是项目所有者才能使用 App Services CLI 创建模板应用。

    • 要了解有关安装 App Services CLI 的更多信息,请参阅安装 App Services CLI 。安装后,使用 Atlas 项目的 API 密钥运行登录命令。

本教程基于名为 swiftui.todo.flex 的 SwiftUI 灵活同步模板应用。我们先使用默认应用,然后在其上构建新功能。

要了解有关模板应用的更多信息,请参阅模板应用

如果您还没有 Atlas 帐号,请注册以部署“模板应用程序”。

按照“创建App Services App”指南中描述的步骤操作,然后选择 Create App from Template 。 选择Real-time Sync模板。 这将创建一个预先配置为与Device Sync模板应用客户端之一一起使用的App Services App 。

创建模板应用后,用户界面会显示一个标有 Get the Front-end Code for your Template 的模态窗口。此模态窗口提供有关将模板应用客户端代码下载为 .zip 文件或使用 App Services CLI 获取客户端的说明。

选择 .zip 或 App Services CLI 方法后,请按照屏幕上的说明获取客户端代码。对于本教程,请选择 SwiftUI (iOS + SwiftUI) 客户端代码。

注意

默认的Windows ZIP 实用程序可能会显示 .zip 文件为空。 如果遇到这种情况,请使用可用的第三方 zip 程序。

appservices apps create 命令设置后端,并创建一个 SwiftUI 模板应用,供您用作本教程的基础。

在终端窗口中运行以下命令,创建一个名为“MyTutorialApp”的应用,将该应用部署在 US-VA 地区,并将其环境设置为“开发”(而不是生产或 QA)。

appservices app create \
--name MyTutorialApp \
--template swiftui.todo.flex \
--deployment-model global \
--environment development

该命令在当前路径中创建一个新目录,其名称与 --name 标志的值相同。

Github您可以创建分支并克隆包含Device Sync 客户端代码的 存储库。SwiftUI客户端代码位于 https://github.com/mongodb/template-app-swiftui-todo。

如果您使用此过程来获取客户端代码,则必须创建一个模板应用以配合客户端使用。按照创建模板应用中的说明操作,使用 Atlas App Services 用户界面、App Services CLI 或 Admin API 创建 Device Sync 模板应用。

1

在 Xcode 中打开前端客户端的 App.xcodeproj

如果您将客户端下载为 .zip 文件或已克隆客户端 GitHub 存储库,则须手动将 App Services App ID 插入客户端中的相应位置。按照客户端 README.md 中的 Configuration 说明来了解在何处插入 App ID。

2

当 Swift Package Manager 下载最新版本的 Realm Swift SDK 时,花几分钟时间探索项目的组织方式。在 App 目录中,您可以看到一些值得注意的文件:

file
用途
AppConfig.swift
此文件包含从 Realm.plist 读取 appIdbaseUrl 的逻辑。它预填充 Template 应用的 appId
App.swift

此文件使用 AppConfig.swift 中的值初始化 RealmSwift.AppApp 是您的应用与 App Services 后端通信的方式。它支持登录和身份验证。此文件还包含监听 Device Sync 错误的错误处理程序。

要进一步了解如何自定义应用配置,请参阅:连接到 Atlas App Services 后端

此文件也是 SwiftUI 应用的入口点。我们将 App 传递给观察应用状态的 ContentView,以确定用户身份验证状态。

在本教程中,你将使用以下文件:

file
用途
Item.Swift
该文件位于项目的根目录,定义了我们存储在数据库中的 Realm 对象。
CreateItemView.swift
此文件位于 Views 目录中,提供将新项目添加到清单中的功能。
ContentView.Swift
此文件位于 Views 目录中,定义灵活同步订阅。
3

无需对代码进行任何更改,您应该能够在 iOS 模拟器或物理设备上运行该应用。

运行应用,注册一个新用户帐户,然后将新事项添加到待办事项清单中。

4

登录 Atlas App Services。在 Data Services 标签页中,单击 Browse Collections。在数据库列表中,找到并展开 todo 数据库,然后找到并展开 Item 集合。您应该会看到在此集合中创建的文档。

1

现在您已经确认一切都按预期进行,我们可以添加更改。在本教程中,我们决定为每个事项添加“priority”属性,以便我们可以按事项的优先级过滤事项。优先级属性使用 PriorityLevel 枚举来限制可能的值。

为此,请按照以下步骤操作:

  1. 在 Xcode 中打开 App.xcodeproj

  2. 打开 Item.swift 类文件。

  3. 将以下属性添加到 Item 类:

    @Persisted var priority: PriorityLevel
  4. 还要在Item类下面添加一个 PriorityLevelPersistableEnum

    class Item: Object, ObjectKeyIdentifiable {
    @Persisted(primaryKey: true) var _id: ObjectId
    @Persisted var isComplete = false
    @Persisted var summary: String
    @Persisted var owner_id: String
    @Persisted var priority: PriorityLevel
    }
    enum PriorityLevel: Int, PersistableEnum, CaseIterable {
    case severe = 0
    case high = 1
    case medium = 2
    case low = 3
    var description: String {
    switch self {
    case .severe: return "Severe"
    case .high: return "High"
    case .medium: return "Medium"
    case .low: return "Low"
    }
    }
    }

    PersistableEnum 是直接在 Realm 中将枚举类型标记为可持久的协议。我们在这里将枚举的类型设置为 Int 而不是 String,以便稍后我们可以根据数字优先级进行查询。我们使用 description 计算属性在用户界面中显示优先级的字符串表示。

2
  1. Views 目录中,转到 CreateItemView.swift。在现有的 itemSummary 属性下添加新的 @State 属性。暂时将默认值设为中等优先级:

    @State var itemSummary = ""
    @State var priority = PriorityLevel.medium
  2. 现在,在 Form 主体中添加一个选取器,让用户能够选择为新事项设置何种优先级。找到包含按钮的 Section,并在其上方插入以下代码:

    Section(header: Text("Priority")) {
    Picker(selection: $priority, label: Text("Set priority")) {
    ForEach(PriorityLevel.allCases, id: \.self) { priority in
    Text(priority.description)
    }
    }
    }
  3. 现在,向下移动到 Button(action:,当用户按下 Save 按钮时,它会设置 newItem 的值。在 newItem.summary 下方添加一行来同时设置 priority 属性:

    newItem.summary = itemSummary
    newItem.priority = priority
3

此时,您可以再次运行应用程序。使用本教程前面创建的帐户登录。您将看到先前创建的一个列项。添加新列项,您将看到现在可以设置优先级。为优先级选择 High 并保存条目。

现在切换回浏览器中的 Atlas 数据页面,并刷新 Item 集合。您现在应该会看到添加了 priority 字段并将其设置为1 的新项目。现有项目没有 priority 字段。

集合中的两个项目
点击放大

注意

为什么没有中断同步?

向 Realm 对象添加属性不是一项重大更改,因此不需要重置客户端。模板应用启用了开发模式,因此对客户端 Realm 对象的更改会反映在服务器端模式中。有关更多信息,请参阅开发模式更新数据模型

1

ContentView.swift 文件中,我们创建了灵活同步订阅,其中定义了我们与用户设备和帐户同步的文档。查找我们设置初始订阅的 let config = user.flexibleSyncConfiguration(initialSubscriptions: 变量。在 subscriptions.append() 方法中,您可以看到我们当前订阅 owner_id 属性与经过身份验证的用户 ID 匹配的所有文档。我们希望保持这一点,但 同步标记为高或严重优先级的事项。

因此,我们将 PriorityLevel 枚举设置为 Int 类型,最高优先级(严重)的值为 0,最低优先级(低)的值为 3。我们可以直接将一个整数 (Int) 与优先级属性进行比较。为此,请更新查询语句以包含优先级等于或小于 PriorityLevel.High(或 1)的文档,如下所示。

我们还将添加布尔型参数 reRunOnOpen,并将其设置为 true,即强制订阅查询在每次打开应用时重新计算要同步的文档。

let config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
if let foundSubscription = subs.first(named: Constants.myItems) {
foundSubscription.updateQuery(toType: Item.self, where: {
$0.owner_id == user.id && $0.priority <= PriorityLevel.high
})
} else {
// No subscription - create it
subs.append(QuerySubscription<Item>(name: Constants.myItems) {
$0.owner_id == user.id && $0.priority <= PriorityLevel.high
})
}
}, rerunOnOpen: true)
2

再次运行应用程序。使用本教程前面创建的帐户登录。因为我们添加了 reRunOnOpen,所以应用应该仅重新同步与灵活同步查询匹配的文档。在 Realm 重新同步文档集合的初始时刻之后,您将只能看到您创建的新的高优先级事项。

您最初创建的事项文档未同步,因为它没有priority 字段。如果希望同步此事项,您可以在 Atlas 用户界面中编辑文档并为优先级字段添加值。

提示

在启用开发者模式的情况下更改订阅

在本教程中,当您首次更改优先级字段的订阅和查询时,该字段将自动添加到 Device Sync Collection Queryable Fields 中。出现这种情况是因为模板应用默认启用了开发模式。如果未启用开发模式,您必须手动将该字段添加为可查询字段,以便在客户端同步查询中使用它。

有关更多信息,请参阅可查询字段

如果要进一步测试此功能,您可以创建各种优先级的事项。您将看到一个优先级较低的新事项短暂出现在事项清单中,继而又消失。同步错误处理程序提供了一条说明此行为的消息,十分有帮助:

ERROR
"Client attempted a write that is outside
of permissions or query filters; it has been reverted"

您还可以在控制台日志中看到此消息。

在这种情况下,Realm 会在本地创建该事项并将其与后端进行同步,然后撤销写入操作,因为它不符合订阅规则。

向现有 Realm 对象添加属性是一项非重大更改,并且开发模式可确保模式更改反映在服务器端。

注意

分享反馈

怎么样?使用页面右下角的 Rate this page 小组件来评价其有效性。如果有任何问题,也可以在 Github 存储库 上提交问题。

来年

什么是 Atlas App Services?