使用 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】:

tasksarraydidSet中,您可以简单地设置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 的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

在 ios 框架项目中存储本地数据的最佳实践

UserDefaults 在 SwiftUI 中与 Toggle 绑定

使用 UserDefaults 为不同用户存储数据

如何使用静态自我实例将模型类保存在 UserDefaults 中?

UserDefaults迅速4

访问令牌持久性最佳实践 (iOS)