大多数浏览器和
Developer App 均支持流媒体播放。
-
认识 SwiftData
SwiftData 是专为 Swift 设计的一种强大且具备表达力的持久化框架。我们将向你展示如何直接使用 Swift 代码进行数据建模,以及如何使用 SwiftData 处理你的模型并与 SwiftUI 集成。
章节
- 0:00 - Intro
- 1:07 - Using the model macro
- 3:17 - Working with your data
- 7:02 - Use SwiftData with SwiftUI
- 8:10 - Wrap-up
资源
相关视频
WWDC23
-
下载
♪ ♪
Ben:嗨 我是 Ben Trumbull 很高兴能向你介绍 SwiftData
SwiftData 是一种强大的 数据建模和管理框架 用于提升 你的现代化 Swift App 与 SwiftUI 一样 它完全 以代码为中心 无需外部文件格式 借助 Swift 全新的 宏系统创造流畅的 API 体验
SwiftData 依靠全新 Swift 语言宏带来的表达能力 来创造流畅的 API 体验 它也能与 SwiftUI 自然整合 并适配其他平台功能 如 CloudKit 和小组件 在今天的讲座中 我们将了解全新的 @Model 宏 和它直接从 Swift 代码中 进行数据建模的能力 我将介绍如何借助 SwiftData 获取和修改你的数据 最后 我将向你介绍一些 能和 SwiftData 进行 无缝协作的其他平台框架 首先我们来了解 @Model @Model 是一种全新的 Swift 宏 可以帮助你在 Swift 代码中 定义模型架构 SwiftData 架构采用 一般 Swift 代码 但如有需要 你可以使用额外的 元数据对属性进行标注 使用这一架构 SwiftData 将为你的模型对象增添强大的功能 只需简单地将 @Model 添加到 class 代码之上 架构就会生成 SwiftData 中的 模型是你 应用数据架构的 可信数据源 驱动着该软件的持续性体验 体验的其中一部分将转变为 该 class 代码的存储属性 并将该属性作为持久化属性 在模型中添加 @Model 将为你开启无限可能 SwiftData 以原生方式 将你要使用的值类型属性 立即转变为表属性使用 这些属性包含基础值类型 例如字符串、int 和 float 也包含更为复杂的值类型 例如 struct、 enum、Codable 类型 以及集合 SwiftData 模型 将引用类型表述为关系 你可以通过模型的关系和集合 在模型类型之间建立链接 @Model 将修改 位于你类型上的全部存储属性 你可以使用属性上的 元数据来影响 SwiftData 创建架构的方式 你可以使用 @Attribute 来添加唯一性约束 也可以使用 @Relationship 来控制反演选项 并详细说明删除传播规则 这改变了模型间链接的行为 你可以借助 @Transient 宏 来使 SwiftData 排除指定属性 这是我们之前 介绍过的 Trip 案例 我将通过为存储属性添加元数据 来调整 SwiftData 的架构生成
我可以在 name 中添加 @Attribute 并指定它必须唯一 我也可以将 @Relationship 加到 bucketList 关系之前 并指示 SwiftData 在删除此旅行时 删除所有相关的心愿单项目 进一步了解 关于 SwiftData 建模的信息 请查看“使用 SwiftData 进行架构建模”讲座 现在 我将介绍如何使用建模类型 以及驱动操作的两个关键对象: SwiftData 中的 ModelContainer 和 ModelContext ModelContainer 为你的 建模类别提供持久化后端 你可以仅指定架构规范 以使用默认设置 也可以通过配置 和迁移选项进行自定义 你可以仅通过指定 想要存储的建模类型列表 来创建 ModelContainer 如果你想进一步自定义这个容器 可以通过配置更改 URL、 CloudKit、群组容器标识符 以及迁移选项来实现 容器设置好之后 你就可以使用 modelContext 来获取和保存数据了 你还可以使用 SwiftUI 的 视图和场景修改器 来对容器进行设置 并让它在视图环境中 自动建立 模型上下文监控着模型中的所有变动 并提供一系列操作动作 它们是你追踪更新、 获取数据、保存更改 和撤销更改的界面 在 SwiftUI 中 你一般可以在创建 modelContainer 后 从视图环境中 获取 modelContext 在视图层次结构外 你可以要求模型容器 提供一个与 main actor 绑定的上下文 你也可以轻松地 针对给定模型容器实例化新上下文 有了上下文之后 你就可以开始获取数据了 SwiftData 受益于全新的 Swift 原生类型 如 Predicate 和 FetchDescriptor 以及针对 Swift 原生 SortDescriptor 的重大升级
Predicate 是 iOS 17 中的新功能 它采用 Swift 原生类型 并使用 Swift 宏进行强类型构建 它经由完全类型检查 可以视作 现代 NSPredicate 的替代品 在 Xcode 的支持下 实现 Predicate 也很容易 比如使用自动填充 以下是几个在 Trip App 示例 中构建 Predicate 的例子 首先 我可以指定 所有以纽约为目的地的旅行 将查询范围缩小到生日旅行 然后指明我们 只对未来计划的旅行感兴趣 而将过去已有的旅行排除 决定好抓取哪些旅行数据之后 我们可以使用新的 FetchDescriptor 类型 并指示 ModelContext 获取这些旅行的数据 配合 FetchDescriptor 使用的 Swift SortDescriptor 也进行了一些更新 以支持 Swift 原生类型 和 keypath 我们也可以用 SortDescriptor 指定顺序 对获取的 Trips 数据进行整理 FetchDescriptor 也提供多种途径 来进行定制化 SwiftData 查询 除了判断条件和排序 你也可以指定相关对象 进行预抓取、限制结果计数 以及从结果中排除 未保存的更改等操作 SwiftData 通过 ModelContext 驱动这些操作 让创建、删除和更改数据变得简便 在像其他任何 Swift 类代码 一样创建模型对象之后 可将其插入上下文 并开始使用 SwiftData 功能 例如更改追踪和持久化 删除持久化对象时 只需指示 ModelContext 对其进行标记并删除 要保存以上这些及其他待定更改 你也可以要求 ModelContext 进行保存并将它们 交付到持久化容器 在模型对象上更改属性值同样简单 只需像往常一样 使用属性 setter 即可 @Model 宏可以修改你的存储属性 来帮助 ModelCotext 自动追踪你的更改 并将它们纳入下一次保存操作中 进一步了解关于 SwiftData 容器和上下文 以及如何驱动其操作的更多信息 请查看“深入了解 SwiftData”讲座 SwiftData 是以 SwiftUI 为基础进行构建的 两者适合搭配使用 SwiftUI 可以让你简便地 开始使用 SwiftData 无论是设置 SwiftData 容器、 获取数据还是驱动视图升级 我们都建立了 API 这些 API 直接对这些框架进行整合 全新的 SwiftUI 场景 和视图修改器是 创建 SwiftData App 最简便的方式 有了 SwiftUI 你可以配置数据存储、 更改选项、启用撤销 和切换自动保存 SwiftUI 会在自身环境中 传播你的模型上下文 设置完成后 开启数据使用最简单的方法 是借助新的 @Query 属性包装器 只需一行代码 你就可以轻松地加载和筛选 数据库中存储的全部内容 SwiftData 支持针对建模属性的 全新可监控功能 SwiftUI 将自动刷新 一切针对监控中属性的更改 将 SwiftUI 和 SwiftData 配合使用 你将创建出充满吸引力的强大 App 如想进一步了解怎样配合使用各类框架 请查看“使用 SwiftData 创建 App”讲座
SwiftData 是一款强大的 全新数据管理解决方案 专为向 Swift 功能 提供一流支持而设计 它使用 Swift 全新的宏系统 完全以你的代码为中心 使用 @model 设置架构 并对模型容器的持久化体验进行配置 你可以轻松地启用持久化、撤销、重做、 进行 iCloud 同步 和小组件开发等功能 现在就使用 SwiftUI 的无缝整合功能 在你的 App 中构建 SwiftData 吧 我们期待着你对 SwiftData 的使用 感谢你的观看! ♪ ♪
-
-
1:27 - Adding @Model to Trip
import SwiftData @Model class Trip { var name: String var destination: String var endDate: Date var startDate: Date var bucketList: [BucketListItem]? = [] var livingAccommodation: LivingAccommodation? }
-
2:46 - Providing options for @Attribute and @Relationship
@Model class Trip { @Attribute(.unique) var name: String var destination: String var endDate: Date var startDate: Date @Relationship(.cascade) var bucketList: [BucketListItem]? = [] var livingAccommodation: LivingAccommodation? }
-
3:43 - Initialize a ModelContainer
// Initialize with only a schema let container = try ModelContainer([Trip.self, LivingAccommodation.self]) // Initialize with configurations let container = try ModelContainer( for: [Trip.self, LivingAccommodation.self], configurations: ModelConfiguration(url: URL("path")) )
-
3:58 - Creating a model container in SwiftUI
import SwiftUI @main struct TripsApp: App { var body: some Scene { WindowGroup { ContentView() } .modelContainer( for: [Trip.self, LivingAccommodation.self] ) } }
-
4:20 - Accessing the environment's ModelContext
import SwiftUI struct ContextView : View { @Environment(\.modelContext) private var context }
-
5:13 - Building a predicate
let today = Date() let tripPredicate = #Predicate<Trip> { $0.destination == "New York" && $0.name.contains("birthday") && $0.startDate > today }
-
5:32 - Fetching with a FetchDescriptor
let descriptor = FetchDescriptor<Trip>(predicate: tripPredicate) let trips = try context.fetch(descriptor)
-
5:46 - Fetching with fetch and sort descriptors
let descriptor = FetchDescriptor<Trip>( sortBy: SortDescriptor(\Trip.name), predicate: tripPredicate ) let trips = try context.fetch(descriptor)
-
6:15 - Working with a ModelContext
var myTrip = Trip(name: "Birthday Trip", destination: "New York") // Insert a new trip context.insert(myTrip) // Delete an existing trip context.delete(myTrip) // Manually save changes to the context try context.save()
-
7:38 - Using @Query in SwiftUI
import SwiftUI struct ContentView: View { @Query(sort: \.startDate, order: .reverse) var trips: [Trip] @Environment(\.modelContext) var modelContext var body: some View { NavigationStack() { List { ForEach(trips) { trip in // ... } } } } }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。