|
|
# SwiftData 集成说明
|
|
|
|
|
|
## 🎯 概述
|
|
|
|
|
|
成功将历史记录功能从 `UserDefaults` 迁移到 `SwiftData`,这是 iOS 17.0+ 的现代数据持久化框架,提供更好的性能、类型安全和功能。
|
|
|
|
|
|
## 🔄 迁移内容
|
|
|
|
|
|
### 1. **数据模型变更**
|
|
|
|
|
|
#### 迁移前 (UserDefaults)
|
|
|
```swift
|
|
|
struct HistoryItem: Identifiable, Codable, Equatable {
|
|
|
let id = UUID()
|
|
|
let content: String
|
|
|
let dataType: DataType
|
|
|
let dataSource: DataSource
|
|
|
let createdAt: Date
|
|
|
var isFavorite: Bool
|
|
|
// ... 其他属性
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### 迁移后 (SwiftData)
|
|
|
```swift
|
|
|
@Model
|
|
|
final class HistoryItem {
|
|
|
@Attribute(.unique) var id: UUID
|
|
|
var content: String
|
|
|
var dataType: DataType
|
|
|
var dataSource: DataSource
|
|
|
var createdAt: Date
|
|
|
var isFavorite: Bool
|
|
|
// ... 其他属性
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 2. **数据管理器变更**
|
|
|
|
|
|
#### 迁移前 (UserDefaults)
|
|
|
```swift
|
|
|
class HistoryManager: ObservableObject {
|
|
|
@Published var historyItems: [HistoryItem] = []
|
|
|
private let userDefaults = UserDefaults.standard
|
|
|
|
|
|
// 使用 JSON 编码/解码
|
|
|
private func saveHistory() {
|
|
|
if let encoded = try? JSONEncoder().encode(historyItems) {
|
|
|
userDefaults.set(encoded, forKey: historyKey)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### 迁移后 (SwiftData)
|
|
|
```swift
|
|
|
@MainActor
|
|
|
class HistoryManager: ObservableObject {
|
|
|
@Published var historyItems: [HistoryItem] = []
|
|
|
private let modelContext: ModelContext
|
|
|
|
|
|
// 使用 SwiftData 的 ModelContext
|
|
|
private func saveHistory() {
|
|
|
do {
|
|
|
try modelContext.save()
|
|
|
} catch {
|
|
|
print("保存历史记录失败: \(error)")
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 3. **视图层变更**
|
|
|
|
|
|
#### 迁移前
|
|
|
```swift
|
|
|
struct HistoryView: View {
|
|
|
@StateObject private var historyManager = HistoryManager()
|
|
|
// ... 其他代码
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### 迁移后
|
|
|
```swift
|
|
|
struct HistoryView: View {
|
|
|
@Environment(\.modelContext) private var modelContext
|
|
|
@Query(sort: \HistoryItem.createdAt, order: .reverse) private var allHistoryItems: [HistoryItem]
|
|
|
// ... 其他代码
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 🚀 SwiftData 的优势
|
|
|
|
|
|
### 1. **性能提升**
|
|
|
- **自动优化**: SwiftData 自动优化查询和存储
|
|
|
- **内存管理**: 更好的内存管理和垃圾回收
|
|
|
- **批量操作**: 支持高效的批量插入、更新、删除
|
|
|
|
|
|
### 2. **类型安全**
|
|
|
- **编译时检查**: 在编译时检查数据模型的一致性
|
|
|
- **强类型**: 避免运行时类型错误
|
|
|
- **自动同步**: 数据模型变更时自动更新相关代码
|
|
|
|
|
|
### 3. **功能丰富**
|
|
|
- **关系支持**: 支持一对一、一对多、多对多关系
|
|
|
- **查询优化**: 支持复杂的查询和排序
|
|
|
- **事务支持**: 支持 ACID 事务
|
|
|
- **迁移支持**: 支持数据模型版本迁移
|
|
|
|
|
|
### 4. **开发体验**
|
|
|
- **声明式语法**: 使用 `@Model` 和 `@Query` 等属性包装器
|
|
|
- **自动同步**: 数据变更自动同步到 UI
|
|
|
- **调试友好**: 更好的调试和错误信息
|
|
|
|
|
|
## 🔧 技术实现细节
|
|
|
|
|
|
### 1. **应用配置**
|
|
|
```swift
|
|
|
@main
|
|
|
struct MyQrCodeApp: App {
|
|
|
var body: some Scene {
|
|
|
WindowGroup {
|
|
|
ContentView()
|
|
|
}
|
|
|
.modelContainer(for: HistoryItem.self)
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 2. **数据查询**
|
|
|
```swift
|
|
|
@Query(sort: \HistoryItem.createdAt, order: .reverse)
|
|
|
private var allHistoryItems: [HistoryItem]
|
|
|
```
|
|
|
|
|
|
### 3. **数据操作**
|
|
|
```swift
|
|
|
// 插入
|
|
|
modelContext.insert(historyItem)
|
|
|
|
|
|
// 删除
|
|
|
modelContext.delete(item)
|
|
|
|
|
|
// 保存
|
|
|
try modelContext.save()
|
|
|
|
|
|
// 查询
|
|
|
let descriptor = FetchDescriptor<HistoryItem>(
|
|
|
sortBy: [SortDescriptor(\.createdAt, order: .reverse)]
|
|
|
)
|
|
|
let items = try modelContext.fetch(descriptor)
|
|
|
```
|
|
|
|
|
|
### 4. **错误处理**
|
|
|
```swift
|
|
|
do {
|
|
|
try modelContext.save()
|
|
|
} catch {
|
|
|
print("保存失败: \(error)")
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 📱 用户界面更新
|
|
|
|
|
|
### 1. **历史记录页面**
|
|
|
- 使用 `@Query` 自动获取和排序数据
|
|
|
- 实时数据同步,无需手动刷新
|
|
|
- 支持搜索、过滤、排序等高级功能
|
|
|
|
|
|
### 2. **创建页面**
|
|
|
- 直接使用 `ModelContext` 插入数据
|
|
|
- 自动保存和错误处理
|
|
|
- 支持事务回滚
|
|
|
|
|
|
### 3. **数据管理**
|
|
|
- 支持批量删除和清空
|
|
|
- 收藏状态实时同步
|
|
|
- 数据变更立即反映到 UI
|
|
|
|
|
|
## 🧪 测试要点
|
|
|
|
|
|
### 1. **功能测试**
|
|
|
- ✅ 历史记录正确保存和加载
|
|
|
- ✅ 搜索和过滤功能正常
|
|
|
- ✅ 收藏状态正确切换
|
|
|
- ✅ 删除和清空功能正常
|
|
|
|
|
|
### 2. **性能测试**
|
|
|
- ✅ 大量数据加载性能
|
|
|
- ✅ 搜索响应速度
|
|
|
- ✅ 内存使用情况
|
|
|
|
|
|
### 3. **兼容性测试**
|
|
|
- ✅ iOS 17.0+ 设备正常工作
|
|
|
- ✅ 数据迁移和版本兼容性
|
|
|
|
|
|
## 🚨 注意事项
|
|
|
|
|
|
### 1. **版本要求**
|
|
|
- **最低版本**: iOS 17.0+
|
|
|
- **推荐版本**: iOS 17.0 或更高
|
|
|
- **回退方案**: 如果需要支持更低版本,可以保留 UserDefaults 作为备选
|
|
|
|
|
|
### 2. **数据迁移**
|
|
|
- 首次使用 SwiftData 时,旧数据需要手动迁移
|
|
|
- 建议实现数据迁移策略
|
|
|
- 考虑数据备份和恢复
|
|
|
|
|
|
### 3. **性能考虑**
|
|
|
- 大量数据时考虑分页加载
|
|
|
- 复杂查询时使用适当的索引
|
|
|
- 定期清理过期数据
|
|
|
|
|
|
## 📊 迁移效果对比
|
|
|
|
|
|
| 特性 | UserDefaults | SwiftData |
|
|
|
|------|-------------|-----------|
|
|
|
| 性能 | 中等 | 优秀 |
|
|
|
| 类型安全 | 低 | 高 |
|
|
|
| 功能丰富度 | 基础 | 丰富 |
|
|
|
| 开发体验 | 一般 | 优秀 |
|
|
|
| 内存管理 | 手动 | 自动 |
|
|
|
| 查询能力 | 有限 | 强大 |
|
|
|
| 关系支持 | 无 | 完整 |
|
|
|
| 事务支持 | 无 | 完整 |
|
|
|
|
|
|
## 🔮 未来扩展
|
|
|
|
|
|
### 1. **数据关系**
|
|
|
- 支持二维码和条形码的分类标签
|
|
|
- 支持用户自定义分组
|
|
|
- 支持数据导入/导出
|
|
|
|
|
|
### 2. **云同步**
|
|
|
- 支持 iCloud 同步
|
|
|
- 支持多设备数据同步
|
|
|
- 支持数据备份和恢复
|
|
|
|
|
|
### 3. **高级功能**
|
|
|
- 支持数据分析和统计
|
|
|
- 支持智能搜索和推荐
|
|
|
- 支持数据压缩和优化
|
|
|
|
|
|
## 📝 总结
|
|
|
|
|
|
通过这次迁移,我们成功将历史记录功能升级到 SwiftData:
|
|
|
|
|
|
1. **性能提升**: 更好的数据操作性能和内存管理
|
|
|
2. **类型安全**: 编译时类型检查和错误预防
|
|
|
3. **功能丰富**: 支持复杂查询、关系、事务等高级功能
|
|
|
4. **开发体验**: 声明式语法和自动同步,提升开发效率
|
|
|
5. **未来扩展**: 为后续功能扩展奠定坚实基础
|
|
|
|
|
|
SwiftData 的集成标志着应用数据层的重要升级,为用户提供更流畅、更可靠的体验。🎉 |