iOS 应用中的数据持久化
核心决策
选择能解决问题的最简单持久化方法。大多数应用不需要复杂的数据库。从简单开始,只有当您有特定原因时才增加复杂性。
UserDefaults:用于简单偏好设置
何时使用
设置、偏好、小型状态片段。切换开关、选择的主题、用户偏好。任何自然的键值对且大小在几 KB 以内的内容。
示例
// Save
UserDefaults.standard.set(true, forKey: "darkModeEnabled")
// Read
let isDarkMode = UserDefaults.standard.bool(forKey: "darkModeEnabled")
何时不该使用
不要存储大量数据。不要存储敏感信息(应使用 Keychain)。不要用于需要结构或关系的数据。UserDefaults 是一个字典——请像对待字典一样对待它。
Codable 与 FileManager:用于结构化数据
何时使用
当您有需要持久化的自定义类型时。任务列表、笔记、日志条目,以及任何可以放入内存的结构化数据。这通常是独立开发的最佳选择——实现简单快速,功能足以应对大多数场景。
示例
struct Note: Codable, Identifiable {
let id: UUID
var title: String
var content: String
var createdAt: Date
}
// Save
func saveNotes(_ notes: [Note]) {
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(notes) {
let url = getDocumentsDirectory().appendingPathComponent("notes.json")
try? encoded.write(to: url)
}
}
// Load
func loadNotes() -> [Note] {
let url = getDocumentsDirectory().appendingPathComponent("notes.json")
guard let data = try? Data(contentsOf: url) else { return [] }
let decoder = JSONDecoder()
return (try? decoder.decode([Note].self, from: data)) ?? []
}
func getDocumentsDirectory() -> URL {
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
}
优点
简单。无依赖。易于调试(JSON 文件易于阅读)。对版本控制友好。您可以打开文件查看确切存储的内容。迁移只需转换 JSON。
Core Data:用于复杂关系
何时使用
当您需要数据模型之间的关系时。当您需要高效查询数据子集时。当您处理无法放入内存的大型数据集时。当您需要内置的撤销/重做功能时。
何时不该使用
不要仅仅因为 Core Data 看起来“专业”就使用它。复杂性成本是真实的。如果您的数据可以放入内存且没有复杂的关系,Codable 与 FileManager 可能更简单。
现实检查
Core Data 有学习曲线。托管对象上下文、抓取请求、关系、迁移——这些都增加了复杂性。确保收益大于成本。对于许多独立应用来说,并不值得。
CloudKit:用于同步
何时使用
当用户需要在多个设备上访问数据时。当您想要同步而不想运行自己的服务器时。当您可以接受将 iCloud 生态系统作为必要条件时。
重要考虑因素
CloudKit 功能强大,但需要仔细处理错误。用户可能登出了 iCloud,存储空间可能不足,网络可能不可用。您的应用必须支持离线工作,并能优雅处理同步失败。这比听起来要复杂。
决策框架
从这里开始
- 仅仅是设置吗?使用 UserDefaults。
- 是可以放入内存的结构化数据吗?使用 Codable + FileManager。
- 需要复杂的查询或关系吗?考虑使用 Core Data。
- 需要跨设备同步吗?添加 CloudKit 或其他同步方案。
迁移路径
从简单开始。您以后随时可以迁移到更复杂的方案。从 Codable 转向 Core Data 需要工作,但并非不可逾越。为了“以防万一”而从第一天就开始使用 Core Data 会增加复杂性——而您可能永远不需要它。
实用提示
始终处理错误
文件保存可能会失败。磁盘可能会满。权限可能会被拒绝。请优雅地处理这些情况。至少要记录错误。更好的做法是:向用户显示清晰的信息并提供选项(重试、保存到其他地方等)。
频繁保存
在每次更改时或通过短定时器自动保存。永远不要要求用户手动保存。永远不要因为应用崩溃而丢失数据。保存的成本很低——丢失数据的代价很高。
测试数据丢失场景
在保存中途强行关闭应用。填满磁盘。在低存储空间下测试。将设备切换到飞行模式。您的持久化层应该在不丢失用户数据的情况下处理这些情况。
目标
用户永远不应该思考他们的数据是如何存储的。每当他们打开应用时,数据就应该可靠地出现在那里。这就是好的持久化所呈现的样子——隐形、可靠且实现简单。
需要在真实项目里做这些技术取舍?
数据持久化通常不是单独决策,而是 iOS 产品范围、性能与迭代节奏的一部分。Shawn Studio 可以在真实项目中一起梳理这些判断,并把它们落到可上线的实现上。