使用 UserDefaults 的最佳方法
Posted
技术标签:
【中文标题】使用 UserDefaults 的最佳方法【英文标题】:Best approach to use UserDefaults 【发布时间】:2020-02-21 13:28:50 【问题描述】:我刚开始学 swift,决定做第一个 todo 应用程序,我有一个问题。在任何用户操作期间都必须保存所有数据:创建、更改或删除任务。每次调用一个方法来保存数据是一种不好的方法。有什么可以推荐的?
func addItem(itemName: String, isCompleted: Bool = false)
tasks.append(Tasks(taskName: itemName, isCompleted: isCompleted))
saveData()
我将任务存储在一个结构中。在使用该结构之前,我使用了这样的计算属性:
var ToDoItems: [[String: Any]]
set
UserDefaults.standard.set(newValue, forKey: "ToDoDataKey")
UserDefaults.standard.synchronize()
get
if let userData = UserDefaults.standard.array(forKey: "ToDoDataKey") as?
[[String: Any]]
return userData
else
return []
【问题讨论】:
用户默认设置不是保存数据的好地方。当您启动并运行应用程序的其余部分时,它可以作为快速而肮脏的解决方案,但它并不意味着保存大量数据。 【参考方案1】:每次任务数组更改时都无需敲击磁盘。通常的做法是注册 UIApplication notification,它会告诉您您的应用即将停用,并在那里保存为默认值。
您只需要从 viewDidLoad
的默认值中检索,正如您已经被告知的那样。
(在支持多窗口的 ios 13 中,事情有点复杂;请参阅 In iOS 13, when to save data?。)
【讨论】:
【参考方案2】:在tasks
array
的didSet
中,您可以简单地设置UserDefaults
中的当前数组元素。
struct Task: Codable
let taskName: String
let isCompleted: Bool
var tasks = [Task]()
didSet
let data = try? JSONEncoder().encode(tasks)
UserDefaults.standard.set(data, forKey: "ToDoDataKey")
func addItem(itemName: String, isCompleted: Bool = false)
tasks.append(Task(taskName: itemName, isCompleted: isCompleted))
这将确保UserDefaults
中的数据与当前内存中的数据同步。
并且仅在viewDidLoad()
中获取数据,其中将首次加载数据。
func fetchTasks() -> [Task]
if let data = UserDefaults.standard.data(forKey: "ToDoDataKey"), let tasks = try? JSONDecoder().decode([Task].self, from: data)
return tasks
return []
在viewDidLoad()
中致电fetchTasks()
。
【讨论】:
将 json 数据保存在属性列表中没有任何意义。为什么不直接将 JSON 数据保存到应用程序支持目录中的磁盘? 请注意,数据大小会大大增加,存储在 UserDefaults 中时会不必要地进行 base64 编码。以上是关于使用 UserDefaults 的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
UserDefaults 在 SwiftUI 中与 Toggle 绑定