教程:附带 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 快速入门。
先决条件
确保您已安装必要的软件。 Swift SDK 需要 Xcode 版本13 。1 或更高版本。
从模板开始
本教程基于名为 swiftui.todo.flex
的 SwiftUI 灵活同步模板应用。我们先使用默认应用,然后在其上构建新功能。
要了解有关模板应用的更多信息,请参阅模板应用。
如果您还没有 Atlas 帐户,请注册以部署模板应用。
探索模板应用
探索应用结构
当 Swift Package Manager 下载最新版本的 Realm Swift SDK 时,花几分钟时间探索项目的组织方式。在 App 目录中,您可以看到一些值得注意的文件:
file | 用途 |
---|---|
AppConfig.swift | 此文件包含从 Realm.plist 读取 appId 和 baseUrl 的逻辑。它预填充 Template 应用的 appId 。 |
App.swift | 此文件使用 要了解有关如何自定义应用程序配置的更多信息,请参阅:连接到 Atlas App Services 后端。 此文件也是 SwiftUI 应用的入口点。我们将 |
在本教程中,你将使用以下文件:
file | 用途 |
---|---|
Item.Swift | 该文件位于项目的根目录,定义了我们存储在数据库中的 Realm 对象。 |
CreateItemView.swift | 此文件位于 Views 目录中,提供将新项目添加到清单中的功能。 |
ContentView.Swift | 此文件位于 Views 目录中,定义灵活同步订阅。 |
检查后端
登录Atlas App Services 。在Data Services标签页中,单击Browse Collections 。在数据库列表中,找到并展开todo数据库,然后找到并展开Item集合。您应该会看到在此集合中创建的文档。
修改应用程序
添加新属性
向模型添加属性
现在您已经确认一切都按预期进行,我们可以添加更改。在本教程中,我们决定为每个事项添加“priority”属性,以便我们可以按事项的优先级过滤事项。优先级属性使用 PriorityLevel 枚举来限制可能的值。
为此,请按照以下步骤操作:
在 Xcode 中打开
App.xcodeproj
。打开
Item.swift
类文件。将以下属性添加到
Item
类:var priority: PriorityLevel 还要在
Item
类下面添加一个 PriorityLevelPersistableEnum
:class Item: Object, ObjectKeyIdentifiable { true) var _id: ObjectId (primaryKey:var isComplete = false var summary: String var owner_id: String 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
计算属性在用户界面中显示优先级的字符串表示形式。
创建新事项时设置优先级
在
Views
目录中,转到CreateItemView.swift
。在现有的itemSummary
属性下添加新的@State
属性。暂时将默认值设为中等优先级:var itemSummary = "" var priority = PriorityLevel.medium 现在,在
Form
主体中添加一个选取器,让用户能够选择为新事项设置何种优先级。找到包含按钮的Section
,并在其上方插入以下代码:Section(header: Text("Priority")) { Picker(selection: $priority, label: Text("Set priority")) { ForEach(PriorityLevel.allCases, id: \.self) { priority in Text(priority.description) } } } 现在,向下移动到
Button(action:
,当用户按下Save
按钮时,它会设置newItem
的值。在newItem.summary
下方添加一行来同时设置priority
属性:newItem.summary = itemSummary newItem.priority = priority
更改订阅
更新订阅
在 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)
运行和测试
再次运行应用程序。使用本教程前面创建的帐户登录。因为我们添加了 reRunOnOpen
,所以应用应该仅重新同步与灵活同步查询匹配的文档。在 Realm 重新同步文档集合的初始时刻之后,您将只能看到您创建的新的高优先级事项。
您最初创建的事项文档未同步,因为它没有priority
字段。如果希望同步此事项,您可以在 Atlas 用户界面中编辑文档并为优先级字段添加值。
如果要进一步测试此功能,您可以创建各种优先级的事项。您将看到一个优先级较低的新事项短暂出现在事项清单中,继而又消失。同步错误处理程序提供了一条说明此行为的消息,十分有帮助:
ERROR "Client attempted a write that is outside of permissions or query filters; it has been reverted"
您还可以在控制台日志中看到此消息。
在这种情况下,Realm 会在本地创建该事项并将其与后端进行同步,然后撤销写入操作,因为它不符合订阅规则。
结论
向现有 Realm 对象添加属性是一项非重大更改,并且开发模式可确保模式更改反映在服务器端。
接下来的步骤
考虑将新的
Priority
属性添加到ItemList
、ItemRow
、和ItemDetail
视图。加入MongoDB Community 论坛,向其他 MongoDB 开发者和技术专家学习。
探索工程和专家提供的示例项目。
注意
分享反馈
怎么样?使用页面右下角的 Share Feedback(分享反馈)选项卡,告诉我们本教程是否有帮助或者您是否有任何问题。