大多数浏览器和
Developer App 均支持流媒体播放。
-
迁移到 SwiftData
了解如何在 App 中开始使用 SwiftData。我们将向你展示如何使用 Xcode 从现有的 Core Data 对象模型中生成模型类,结合此前的实施使用 SwiftData,甚至完全替换现有的解决方案。 在观看本次讲座之前,请务必观看“认识 SwiftData”。
章节
- 0:00 - Intro
- 1:06 - Generate model classes
- 3:05 - Complete adoption
- 6:43 - Coexists with Core Data
- 10:47 - Wrap-up
资源
相关视频
WWDC23
-
下载
♪ ♪
Luvena:大家好! 我是 Luvena 很高兴与你分享 如何将 Core Data App 迁移到 SwiftData 这是一种可与 Core Data 共存的 Swift 原生持久化框架 我将介绍一些 如何在 Core Data App 中 采用 SwiftData 的常见用例 无论你是否准备好从 Core Data 完全过渡到 SwiftData 还是希望逐步采用 SwiftData 与 Core Data 实现共存 首先 我将演示如何使用 managed object model 编辑助手 生成 SwiftData 模型类 接着 我会演示在现有 Core Data App 中 完整采用 SwiftData 的流程 最后 我会向你介绍 Core Data 和 SwiftData 之间的共存方式 以应对完全转换到 SwiftData 对你的用例来说不可行的情况 接下来 我会首先介绍一下 生成模型类的流程 在 SwiftData 中 你需要过渡到 使用代码中的模型来设置架构 其中一种简单的方法是 使用 Core Data 中的 managed object model 帮助你生成 SwiftData 模型 我来向你演示一下 如何进行这种过渡 在这里 我创建了一个名为 SampleTrips 的 Core Data App 该 App 可用于帮助用户 规划即将到来的旅行行程 这是模型文件 其中包含了 数据及其组织方式的信息 我有三个实体: Trip、LivingAccommodation 以及 BucketListItem 每个 Trip 对应一个 LivingAccommodation 以及 一个表示期望旅行活动的 BucketListItem 这三个实体以这样的方式进行组织 现在 我将会生成 用于捕获这些信息的 SwiftData 类 尽管不需要使用 Core Data 的 managed object model 来创建 这些 SwiftData 类 但如果 我有一个既有的 Core Data 模型 就可以使用此模型 生成 SwiftData 类 该 SwiftData 类 以既有模型中已有的组织为基础 接下来 我将对该用例进行演示 为了实现该用例 我需要使用 managed object model 编辑助手 在选择模型文件后 我导航至菜单栏 选择“编辑” 并点击“创建 SwiftData Code” 现在 我可以为 3 个 既有的实体生成文件 如果是创建新的 Swift App 你也可以选择从头开始 创建 SwiftData 模型 而不需要使用该助手 这些是我刚刚创建的文件 你的 Swift 类型应该遵循 Model 并且每个类型都可以捕获属性等 实体信息作为变量 对于 Trip 来说 其属性就是 name、 destination、start Date、end Date 以及与其他实体的关系: livingAccommodation 和 bucketListItem 接下来 我将向你介绍 如何完全采用 SwiftData 你将 App 完全迁移 到 SwiftData 的过程 就是使用 SwiftData 堆栈替换 Core Data 堆栈 以结合使用 Swift 原生语言和 SwiftData 的过程 这样做可以让你更清晰地 编写用于持久化数据的代码 并间接地管理一些功能 但在进行该转换前 你需要考虑既有 Core Data 模型的结构 你的 Core Data 模型设计 会参考你的架构 包括实体、实体的属性 以及实体之间的关系 并且 你还需要确保 你的 Core Data 模型设计 在 SwiftData 中能够得到支持 这就意味着 对于 Core Data 中定义的每个实体 都需要有一个对应的模型类型 并且其中实体的名字和属性 与 SwiftData 中的完全匹配 此外 你还需要确保对你的模型 进行彻底的测试 以验证所有功能在 SwiftData 中 是否得到支持 接下来 我会更详细地介绍一下 从 Core Data App 完全迁移到 SwiftData 过程中的一些重点 此前 我已经生成了用于 捕获模型的 Swift 类型 在我准备好这些文件后 我就可以删除此前使用的 Core Data 中的 managed object model 文件 并通过这些 Swift 文件 来管理模型 此外 我还可以删除此前 帮助设置 Core Data 堆栈的 持久化文件 现在 我就可以为 SwiftData 堆栈 设置 modelContainer modelContainer 是一个修饰符 可用于确保组内的所有窗口 都配置为访问同一个持久性容器 通过在 TripsApp 中添加该容器 我可以同时设置容器和上下文 因为 modelContainer 还会在 Environment 中 创建和设置默认 ModelContext ModelContext 可用于跟踪 App 类型中的实例更改 并且 使用 Environment 属性 可以在任何场景或视图中对其进行读取 我已经在 SampleTrips 中 设置了 SwiftData 持久化堆栈 但我还需要进行一些其他更改 首先 我会演示一下 创建对象的工作原理 此前 我们在 Core Data 中 创建新 Trip 的过程与之类似 我会创建一个 Trip 实例 传入 managed object context 然后对其属性进行设置 在 SwiftData 中 我会使用这行代码 创建 Trip 的新实例 这种实例相对更加易读 在有了新的 trip 后 我会将其插入到 modelContext 中 以确保得到持久化 现在 我的 trip 已经实现了持久化 我还想看看如何对其进行保存 以及未来可对其进行何种更改 SwiftData 具有间接保存功能 可以在 UI 生命周期事件上 触发保存操作 并尽可能在上下文 发生更改时保存数据 因此 我可以删除上下文调用的 Core Data 的显式保存 并在上下文发生更改时 依赖间接保存以对数据进行持久化 接下来 我来向你介绍一下 如何获取数据 我可以将一组 trips 封装在 Query 中 然后使用 Query 获取 即将到来的完整 trips 列表 而无需像在 Core Data 中那样 使用 fetch 请求 这样 我就可以从 SwiftData 容器中 获取这些 Trip 对象 并且 我还为 Query 定义了排序顺序 我希望按照旅行开始的日期 进行正向排序 以使最近的旅行位于顶部 此外 Query 还可用于 需要包含谓词的用例 现在 你已经了解了 如何将 Core Data App 完全迁移到 SwiftData 接下来 我将向你介绍 Core Data 和 SwiftData 之间 可以实现共存的情况 在某些情况下 完全迁移可能 是不可行的或是不切实际的 这时 你可以考虑 将部分转换为 SwiftData 共存是指同时存在 两个完全独立的持久化堆栈 一个是 Core Data 堆栈 一个是 SwiftData 堆栈 并且这两个堆栈都会与 同一个持久化存储进行通信 这就意味着 你无需为了添加 SwiftData 代码 完全重写现有的 Code Data 代码 该选项为你在 App 中 采用 SwiftData 提供了更大的灵活性 无论你是否已经在 Core Data 中 拥有了一些数据 还是你仅是面临不允许完全转换至 SwiftData 的其他限制 这里展示的是如何设置两个堆栈 以实现与同一个存储进行通信 在加载持久化存储前 你需要为 container 的 description 设置持久化存储 URL 以确保两个堆栈都写入同一个 URL 此外 你还需要打开持久化历史跟踪 尽管 SwiftData 会自动打开 持久化历史跟踪 但是 Core Data 却不会 当 Core Data 和 SwiftData 共存于 同一个没有设置 持久化历史的 App 中 如果你想在这种情况下 打开持久化历史 存储将会设置为只读模式 在以下几种不同场景中 共存可能会成为你用例的最佳选择 一种场景是为了与现有客户端 保持向后兼容性 由于 SwiftData 仅在 iOS 17 和 macOS Sonoma 中可用 因此 完全切换到 SwiftData 可能 会影响到你当前的 Core Data App 另一种场景是 你可能面临着资源限制 从而很难完全转换到 SwiftData 在这些情况下 使用 SwiftData 进行新的开发 或将 App 部分转换为 SwiftData 从而将 SwiftData 部分合并 可能会有一定作用 但是在进行该转换之前 你需要考虑一下 Core Data 和 SwiftData 之间 实现共存的几点要求 首先 你必须为既有的基于 NSManagedObject 的实体子类 或 SwiftData 类命名空间位置 以避免两者产生冲突 这就意味着不能存在 具有完全相同名称的两个类 因此 其中至少有一个类的名称 需要进行更改 你需要记住的是 尽管你更改了类的名称 但实体的名称始终保持不变 例如 这里是与此前完全相同的 SampleTrips 项目 但这次我想要实现 Core Data 和 SwiftData 共存 这两个类的名称存在冲突 为了区分 SwiftData 和 Core Data 的 Trip 类名 我将 Core Data 的 Trip 类名更改为 CDTrip 你也可以在 managed object model 编辑中进行该操作 此外 你还需要让 Core Data 和 SwiftData 的架构保持同步 SwiftData 架构的新部分必须作为 NSmanaged object model 进行实例化 并且以上两个架构间不能存在分歧 这就意味着属性和关系必须 以完全相同的方式添加到模型中 这样 实体版本的哈希 才能在每个步骤实现匹配 因为不匹配的哈希可能会触发迁移 并删除你不想删除的信息 最后 在合并共存时 你还需要跟踪架构版本 在使用多个 SwiftData 模型版本时 你必须确保所有更改 都得到正确的表示 以便 SwiftData 可以评估差异 你可以通过以下几种方法 实现这一点 请观看“使用 SwiftData 对你的 架构进行建模”讲座 以了解如何使用版本化架构 对于依赖 UIKit 或 AppKit 的 Swift App 这里也有几个可行的选择 可供你使用 SwiftData 第一种方法是共存解决方案 你可以将 UIKitm 代码 绑定到 Core Data 然后 此代码就可以与 SwiftData 并行使用 或者 你也可以将 SwiftData 类 视为 Swift 类 并使用 UIKit 代码 对 Swift 代码进行封装 以上就是本次讲座的全部内容 现在就去探索如何灵活地 将 Core Data App 完全地 或逐步地迁移到 SwiftData 中吧 同时 你也可以观看其他 关于 SwiftData 的精彩讲座 以进行深入了解 感谢你的参与! 我很期待看到你编译的精彩内容! ♪ ♪
-
-
4:37 - Creating a ModelContainer in SwiftUI
@main struct TripsApp: App { var body: some Scene { WindowGroup { ContentView() } .modelContainer( for: [Trip.self, BucketListItem.self, LivingAccommodation.self] ) } }
-
4:57 - Object creation in Core Data
@Environment(\.managedObjectContext) private var viewContext let newTrip = Trip(context: viewContext) newTrip.name = name newTrip.destination = destination newTrip.startDate = startDate newTrip.endDate = endDate
-
5:30 - Object creation in SwiftData
@Environment(\.modelContext) private var modelContext let trip = Trip( name: name, destination: destination, startDate: startDate, endDate: endDate ) modelContext.insert(object: trip)
-
6:16 - Fetch with Query in SwiftData
@Query(sort: \.startDate, order: .forward) var trips: [Trip]
-
7:30 - Setting store path and enabling persistent history tracking in Core Data
let url = URL(fileURLWithPath: "/path/to/Trips.store") if let description = container.persistentStoreDescriptions.first { description.url = url description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) }
-
9:11 - Ensuring Core Data and SwiftData class names are unique
class CDTrip: NSManagedObject { // ... } @Model final class Trip { // ... }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。