简体   繁体   English

Swift:如何在 Userdefaults 中保存和加载包含结构值的字典

[英]Swift: How can I save and load a dictionary with values of a structure in Userdefaults

I've read some posts on the subject on StackOverflow.我在 StackOverflow 上阅读了一些关于该主题的帖子。 As far as I understood it, I can't save every object in Swift immediately in the userdefaults.据我了解,我无法立即将 Swift 中的每个 object 保存在 userdefaults 中。 In the first step I tried to convert my dictionary to an NSData object, but already at this point, I fail.在第一步中,我尝试将我的字典转换为 NSData object,但此时我已经失败了。 What am I doing wrong?我究竟做错了什么? Thanks for your help!谢谢你的帮助!

I want to manage app preferences in the mentioned dictionary.我想在提到的字典中管理应用偏好。 The dictionary with the value of a struct would be the best solution for me.具有结构值的字典对我来说是最好的解决方案。

import Foundation
import UIKit


struct Properties: Codable {
    var v1: String
    var v2: Int
    var v3: Bool
}


let userdefaults = UserDefaults.standard

var dictStruct: Dictionary<String, Properties> = [:]

dictStruct["a"] = Properties(v1: "AAA", v2: 0, v3: false)
dictStruct["b"] = Properties(v1: "BBB", v2: 1, v3: true)


let dataEncoded: Data = try NSKeyedArchiver.archivedData(withRootObject: dictStruct, requiringSecureCoding: false)

userdefaults.set(dataEncoded, forKey: "KeyData")

let dataDecoded = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(userdefaults.object(forKey: "KeyData") as! Data) as! Dictionary<String, Properties>

print(dataDecoded["a"]!.v1)

Playground execution terminated: An error was thrown and was not caught: Error Domain=NSCocoaErrorDomain Code=4866 "Caught exception during archival: -[__SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 0x600000fc73c0... Playground 执行终止:引发错误且未捕获:错误域 = NSCocoaErrorDomain 代码 = 4866 “归档期间捕获异常:-[__SwiftValue encodeWithCoder:]:无法识别的选择器发送到实例 0x600000fc73c0 ...

You are mixing up Codable and NSCoding .您正在混淆CodableNSCoding NSKeyed(Un)Archiver belongs to NSCoding . NSKeyed(Un)Archiver属于NSCoding Don't use it.不要使用它。

The proper API for Codable is PropertyListEncoder/-Decoder Codable 的正确CodablePropertyListEncoder/-Decoder

struct Properties: Codable {
    var v1: String
    var v2: Int
    var v3: Bool
}

let userdefaults = UserDefaults.standard

var dictStruct: Dictionary<String, Properties> = [:]

dictStruct["a"] = Properties(v1: "AAA", v2: 0, v3: false)
dictStruct["b"] = Properties(v1: "BBB", v2: 1, v3: true)

do {
    let dataEncoded = try PropertyListEncoder().encode(dictStruct)

    userdefaults.set(dataEncoded, forKey: "KeyData")

    if let data = userdefaults.data(forKey: "KeyData") {
       let dataDecoded = try PropertyListDecoder().decode([String:Properties].self, from: data)
       print(dataDecoded["a"]!.v1)
    }
} catch { print(error) }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM