什么是 SwiftData?
SwiftData 是苹果在 WWDC23 上推出的全新数据持久化框架,它构建在 Core Data 之上,但提供了更加 Swift 友好的 API。SwiftData 旨在简化数据模型的创建和管理,让开发者能够以更少的代码实现强大的数据持久化功能。
为什么选择 SwiftData?
- Swift 原生支持:专为 Swift 设计,充分利用 Swift 的语言特性
- 声明式语法:使用 Swift 宏简化模型定义
- 与 SwiftUI 深度集成:完美配合 SwiftUI 的生命周期和状态管理
- 性能优化:自动处理批量操作、变更跟踪和内存管理
- CloudKit 集成:轻松实现数据同步
快速开始
1. 定义模型
import SwiftData
@Model
class TodoItem {
var title: String
var isCompleted: Bool
var dueDate: Date
var priority: Int
init(title: String, isCompleted: Bool = false, dueDate: Date, priority: Int = 1) {
self.title = title
self.isCompleted = isCompleted
self.dueDate = dueDate
self.priority = priority
}
}
@Model
宏会自动为你的类添加持久化能力,无需手动处理 Core Data 的复杂设置。
2. 设置 SwiftData 容器
import SwiftUI
@main
struct TodoApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(for: TodoItem.self)
}
}
3. 在视图中使用数据
import SwiftUI
struct TodoListView: View {
@Query var todos: [TodoItem]
@Environment(\.modelContext) private var modelContext
var body: some View {
List {
ForEach(todos) { todo in
TodoRowView(todo: todo)
}
.onDelete { indices in
for index in indices {
modelContext.delete(todos[index])
}
}
}
}
}
核心功能
查询数据
SwiftData 提供了强大的查询功能:
// 基本查询
@Query var allTodos: [TodoItem]
// 带排序的查询
@Query(sort: \.dueDate) var todosByDate: [TodoItem]
// 带谓词的查询
@Query(filter: #Predicate<TodoItem> { $0.isCompleted == false })
var activeTodos: [TodoItem]
// 分页查询
@Query(fetchLimit: 10, fetchOffset: 20) private var paginatedTasks: [TodoItem]
// 动态查询
@Query(filter: predicate, sort: sortOrder, animation: .default)
var filteredTodos: [TodoItem]
动态查询
你可以根据用户的输入或其他条件动态地改变查询参数
struct ContentView: View {
@State private var searchText: String = ""
@Query private var tasks: [TodoItem]
var filteredTasks: [TodoItem] {
if searchText.isEmpty {
return tasks
} else {
return tasks.filter { $0.title.contains(searchText) }
}
}
var body: some View {
VStack {
TextField("Search", text: $searchText)
List(filteredTasks) { task in
Text(task.title)
}
}
}
}
在这个例子中,用户可以在 TextField
中输入搜索文本,然后根据输入动态过滤 tasks
数组。虽然这不是直接通过 @Query
的参数来实现过滤,但它展示了如何根据用户输入动态改变查询结果
数据操作
// 插入新数据
let newTodo = TodoItem(title: "Learn SwiftData", dueDate: Date())
modelContext.insert(newTodo)
// 更新数据
todo.isCompleted = true
// 删除数据
modelContext.delete(todo)
// 保存更改(自动管理,通常不需要手动调用)
try? modelContext.save()
性能优化技巧
-
批量操作:使用
@Query
的animation
参数优化列表更新 -
分页加载:结合
FetchDescriptor
实现分页 -
后台处理:使用
ModelActor
在后台执行数据操作 -
预取关联数据:合理使用
include
优化关联数据加载
总结
SwiftData 为 Swift 开发者提供了一种更现代、更简洁的数据持久化方案。虽然它在复杂场景下可能还不及 Core Data 灵活,但对于大多数应用来说,SwiftData 的简洁性和与 SwiftUI 的深度集成使其成为首选。随着苹果的持续投入,SwiftData 有望成为 iOS/macOS 生态中数据持久化的主流解决方案。