认识 SwiftData
Meet SwiftData
2023年6月5日
一句话判断
SwiftData 用一个 @Model 宏替代了 Core Data 的整个 xcdatamodel 文件——数据持久化终于进入了纯 Swift 时代。
这场 Session 讲了什么
SwiftData 是一个全新的数据建模和管理框架,专为现代 Swift app 设计。它利用 Swift 的新宏系统创建无缝的 API 体验,不依赖外部文件格式。SwiftData 与 SwiftUI 深度集成,同时支持 CloudKit 和 Widgets。
核心是 @Model 宏。只需将 @Model 添加到你的类定义上,SwiftData 就会自动将存储属性转换为持久化属性。它原生支持基本值类型(String、Int、Float)、复杂值类型(struct、enum、Codable 类型,包括集合),并将引用类型自动处理为关系。
SwiftData 提供了两个关键对象:ModelContainer(持久化后端)和 ModelContext(数据操作接口)。ModelContext 支持变更追踪、数据查询、保存和撤销。SwiftUI 的 scene 和 view modifier 让设置变得极其简单。
全新的 Predicate 和 FetchDescriptor 类型是 NSPredicate 的现代替代品,完全类型安全,支持 Xcode 自动补全。
值得深挖的点
Schema 元数据系统让你可以精细控制持久化行为。@Attribute 添加唯一性约束,@Relationship 控制反向关系和删除传播规则,@Transient 排除特定属性。
Predicate 的构建体验是一个巨大提升。告别了 NSPredicate 的字符串拼接噩梦,现在你可以用纯 Swift 语法编写查询条件,享受完整的类型检查和自动补全。
代码片段
// 定义数据模型
@Model
class Trip {
@Attribute(.unique) var name: String
var destination: String
var date: Date
@Relationship(deleteRule: .cascade)
var bucketList: [BucketListItem]
init(name: String, destination: String, date: Date) {
self.name = name
self.destination = destination
self.date = date
self.bucketList = []
}
}
// 配置容器
let container = try ModelContainer(for: Trip.self)
// 使用 Predicate 查询
let predicate = #Predicate<Trip> { trip in
trip.destination == "New York" &&
trip.date > Date.now
}
let descriptor = FetchDescriptor(predicate: predicate)
let trips = try context.fetch(descriptor)
// SwiftUI 集成
@Query var trips: [Trip]
var body: some View {
List(trips) { trip in
Text(trip.name)
}
.modelContainer(for: Trip.self)
}
最佳实践
- 使用
@Attribute(.unique)为需要唯一性的属性添加约束 - 用
@Relationship(deleteRule: .cascade)处理级联删除 - Predicate 完全类型安全,利用 Xcode 自动补全构建查询
- SwiftUI 的
@Query是最简单的数据加载方式 - 通过 view modifier 设置 modelContainer,SwiftUI 自动传播 context
还有什么值得关注
- 参考 “Model your schema with SwiftData” 深入了解建模
- “Dive Deeper into SwiftData” 讲解容器和上下文的高级用法
- “Build an app with SwiftData” 提供完整的实战示例
- SwiftData 支持 CloudKit 同步和 Widget 数据共享