数据持久化
UserDefaults、SwiftData、Core Data。
30 分钟
数据持久化
SwiftUI App 本地存储分层:UserDefaults 存偏好、SwiftData / Core Data 存结构化数据、FileManager 存文件。对照 /roadmaps/swift-ui「数据持久化」节点。
学习目标
- 选择合适的存储方案(轻量 vs 关系型)
- 使用 UserDefaults 与
@AppStorage绑定 UI - 了解 SwiftData
@Model基础 CRUD - 在 SwiftUI 中观察持久化数据变化
核心概念
UserDefaults 与 @AppStorage
// 命令式读写
UserDefaults.standard.set("swift-ui-essentials", forKey: "lastTrack")
let slug = UserDefaults.standard.string(forKey: "lastTrack") ?? ""
// SwiftUI 声明式绑定
struct PreferencesView: View {
@AppStorage("darkMode") private var darkMode = false
@AppStorage("lastTrack") private var lastTrack = ""
var body: some View {
Form {
Toggle("深色模式", isOn: $darkMode)
TextField("上次 Track", text: $lastTrack)
}
}
}
@AppStorage 自动同步 UserDefaults,Toggle/TextField 变更即时持久化。适合主题、引导标记等小数据。
SwiftData 基础
import SwiftData
@Model
final class Bookmark {
var title: String
var url: String
var createdAt: Date
init(title: String, url: String) {
self.title = title
self.url = url
self.createdAt = .now
}
}
struct BookmarkListView: View {
@Environment(\.modelContext) private var context
@Query(sort: \Bookmark.createdAt, order: .reverse) private var bookmarks: [Bookmark]
@State private var newTitle = ""
var body: some View {
List {
ForEach(bookmarks) { item in
VStack(alignment: .leading) {
Text(item.title).font(.headline)
Text(item.url).font(.caption).foregroundStyle(.secondary)
}
}
.onDelete(perform: deleteBookmarks)
}
.navigationTitle("书签")
.toolbar {
Button("添加示例") { addSample() }
}
}
private func addSample() {
let item = Bookmark(title: "SwiftUI 文档", url: "https://developer.apple.com")
context.insert(item)
}
private func deleteBookmarks(at offsets: IndexSet) {
for index in offsets {
context.delete(bookmarks[index])
}
}
}
iOS 17+ SwiftData 用 @Model 宏定义实体, 自动查询并驱动 List 刷新。App 入口需 。