将数据持久化:UserDefaults 与 SwiftUI
2024-01-18 02:03:55
概述
构建应用时,我们通常会面临一个问题:应用重启后,所有的数据都被擦除了。对于有些应用来说,这没什么大不了的,比如计算器或记事本。但对于那些需要存储数据的应用来说,这显然是一个致命的缺陷。
为了解决这个问题,我们需要一种方法来将数据存储在设备上,以便在应用重启后仍能访问它们。在 SwiftUI 中,我们可以使用 UserDefaults 来实现数据持久化。
UserDefaults 简介
UserDefaults 是一个存储键值对的轻量级数据库。它可以存储各种类型的数据,包括字符串、数字、布尔值和数组。UserDefaults 是一个单例,这意味着它在整个应用程序中都是可用的。
我们可以使用 UserDefaults 来存储各种数据,例如:
- 用户设置
- 应用状态
- 游戏数据
- 缓存数据
使用 UserDefaults 存储数据
要使用 UserDefaults 存储数据,我们可以使用 UserDefaults.standard.set(_:forKey:)
方法。该方法有两个参数:第一个参数是要存储的值,第二个参数是键。
例如,我们可以使用以下代码将一个字符串存储到 UserDefaults 中:
UserDefaults.standard.set("Hello, world!", forKey: "greeting")
使用 UserDefaults 加载数据
要使用 UserDefaults 加载数据,我们可以使用 UserDefaults.standard.object(forKey:)
方法。该方法有一个参数:键。
例如,我们可以使用以下代码从 UserDefaults 中加载一个字符串:
let greeting = UserDefaults.standard.object(forKey: "greeting") as? String
如果键不存在,object(forKey:)
方法将返回 nil。
使用 UserDefaults 存储和加载数据示例
现在,我们来看一个使用 UserDefaults 存储和加载数据的示例。
假设我们有一个 SwiftUI 应用,用于管理一个待办事项列表。我们希望在应用重启后仍然能够访问待办事项列表。
我们可以使用 UserDefaults 来存储待办事项列表。首先,我们需要创建一个 ToDoItem
结构体来表示一个待办事项:
struct ToDoItem: Identifiable {
let id = UUID()
let title: String
let completed: Bool
}
然后,我们需要创建一个 ToDoList
类来管理待办事项列表:
class ToDoList: ObservableObject {
@Published var items: [ToDoItem] = []
func save() {
UserDefaults.standard.set(try? JSONEncoder().encode(items), forKey: "toDoList")
}
func load() {
if let data = UserDefaults.standard.object(forKey: "toDoList") as? Data {
if let items = try? JSONDecoder().decode([ToDoItem].self, from: data) {
self.items = items
}
}
}
}
在 ToDoList
类中,我们定义了一个 items
属性来存储待办事项列表。我们还定义了 save()
和 load()
方法来将待办事项列表存储到 UserDefaults 和从 UserDefaults 加载待办事项列表。
在 save()
方法中,我们将 items
属性编码为 JSON 格式,然后将其存储到 UserDefaults 中。在 load()
方法中,我们将从 UserDefaults 中加载 JSON 数据,然后将其解码为 [ToDoItem]
数组,并将其赋值给 items
属性。
最后,我们在 ContentView
中使用 ToDoList
类来管理待办事项列表:
struct ContentView: View {
@ObservedObject var toDoList = ToDoList()
var body: some View {
List {
ForEach(toDoList.items) { item in
Text(item.title)
}
}
.onAppear {
toDoList.load()
}
.onDisappear {
toDoList.save()
}
}
}
在 ContentView
中,我们使用 @ObservedObject
属性包装器来观察 toDoList
类的变化。当 toDoList
类的 items
属性发生变化时,ContentView
也会更新。
我们还在 onAppear()
和 onDisappear()
方法中调用 toDoList
类的 load()
和 save()
方法来在应用启动时加载待办事项列表,并在应用退出时保存待办事项列表。
现在,我们就可以在应用重启后仍然访问待办事项列表了。