在 UserDefaults 中存储字典

Posted

技术标签:

【中文标题】在 UserDefaults 中存储字典【英文标题】:Store dictionary in UserDefaults 【发布时间】:2020-04-26 02:49:14 【问题描述】:

这是与Save dictionary to UserDefaults 类似的方法,但是,它适用于 SwiftUI,而不是像 set 那样使用单行,所以我想用变量将值存储在某个地方,以便我可以轻松调用它。也不同,因为我要求初始化。

我有以下几点:

@Published var mealAndStatus: Dictionary

init() 
    mealAndStatus = ["Breakfast": "initial", "Snack": "notSet", "Lunch": "notSet", "Snack2": "notSet", "Dinner": "notSet"]
    if let storedDay = UserDefaults.standard.value(forKey: "mealAndStatus") 
        mealAndStatus = storedDay as! Dictionary
    

1- 如何在 SwiftUI 的 UserDefaults 中正确存储该字典?

2-那个init,我必须在ContentView的开头调用它吗?或者我可以把它放在另一个 swift 文件上吗?不确定如何调用 init。

我已经用布尔工作做了一个:

@Published var startDay: Bool

init() 
    startDay = true
    if let storedDay = UserDefaults.standard.value(forKey: "startDay") 
        startDay = storedDay as! Bool
    

但字典似乎不起作用。我需要初始化该字典并将其存储在 UserDefaults 中,以便以后可以访问它。任何帮助表示赞赏。

【问题讨论】:

@HalR 让我看看我能不能让它工作,谢谢 @HalR 不,我仍然无法转换功能,我该怎么做? 解决方案:***.com/questions/61333470/… 这不是解决办法,反正我已经找到了,谢谢 怎么不是?什么是? 【参考方案1】:

这是我为 SwiftUI 找到的完美解决方案:

将此存储在某个地方,在我的例子中,我为 UserDefaults 创建了一个类:

@Published var mealAndStatus: [String: Date] =
    UserDefaults.standard.dictionary(forKey: "mealAndStatus") as? [String: Date] ?? [:] 
    didSet 
        UserDefaults.standard.set(self.mealAndStatus, forKey: "mealAndStatus")
    

上面初始化了字典,还创建了一个易于调用并用于更新值的变量。这可以在午餐时间修改并添加新值,这样就可以用我想要的任何东西进行初始化。

此外,现在在 Apple Dev wwdc20 上,他们宣布了一种使用 SwiftUI 处理 UserDefaults 的新方法,这可能比上述方法更好。属性包装器称为:@AppStorage

【讨论】:

【参考方案2】:

使用 JSONEncoder 和 JSONDecoder 将帮助您将任何符合可编码的结构或字典转换为数据。

let arrayKey = "arrayKey"

func store(dictionary: [String: String], key: String) 
    var data: Data?
    let encoder = JSONEncoder()
    do 
        data = try encoder.encode(dictionary)
     catch 
        print("failed to get data")
    
    UserDefaults.standard.set(data, forKey: key)


func fetchDictionay(key: String) -> [String: String]? 
    let decoder = JSONDecoder()
    do 
        
        if let storedData = UserDefaults.standard.data(forKey: key) 
            let newArray = try decoder.decode([String: String].self, from: storedData)
            print("new array: \(newArray)")
            return newArray
        
     catch 
        print("couldn't decode array: \(error)")
    
    return nil


// You would put this where you want to save the dictionary
let mealAndStatus = ["Breakfast": "initial", "Snack": "notSet", "Lunch": "notSet", "Snack2": "notSet", "Dinner": "notSet"]

store(dictionary: mealAndStatus, key: arrayKey)


// You would put this where you want to access the dictionary

let savedDictionary = fetchDictionay(key: arrayKey)

附带说明,您可能不应该使用标准默认值来存储此类内容。将其存储为数据库,或将其保存在文件中,尤其是对数据库或文件进行加密的情况下,可能会更安全一些。

【讨论】:

感谢您向我展示了我不知道的编码器,我一定会研究它,但我现在要做的只是预定义一个包含一些元素的简单字典在应用程序安装时,并将其存储在默认值上。这就是为什么初始化

以上是关于在 UserDefaults 中存储字典的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 从 UserDefaults.standard 存储和提取字典

在 UserDefaults 中访问字典时,类型“任何”没有下标成员

将字典保存到 UserDefaults

如何在 UserDefaults 中重置“AppleLanguages”键的值

错误:试图将堆栈放在不可读的内存中:0x7ffeeafe2af0:使用 userDefaults

只有 NSDictionary 中的属性列表对象(NSNumber),但不能在 UserDefaults 中存储 dict