用户默认不保存词典内容 swift 3

User Defaults not saving dictionary contents in swift 3

我正在尝试向字典中添加键和值,然后添加用户默认的字典并读回字典对象。我有两个问题,非常感谢您的帮助,

1) 为什么从用户默认值中读取的字典是空的?因为我在字典中添加了一个键和一个值,难道不应该将它们保存到我从用户默认值检索的字典中吗?

let defaults = UserDefaults.standard;
var myDict = [String: String]()
myDict["key"] = "value"

defaults.setValue(myDict, forKey: "myDict")


let mydict2 = defaults.object(forKey: "myDict") as? [String: String] ?? [String:String]()
print(mydict2)

2) 如果字典存储了我创建的自定义 class 作为值或键,那么如果字典是这样的:

class Car {
  var engineSize: Int
  var color: String

  init() {
    engineSize = 2000
    color = "blue"
  }

}

class Boat {    
  var surfaceArea: Int
  var weight: Int

  init() {    
    surfaceArea = 3500
    weight = 4000
  }
}

var myDict = [Car: Boat]()

如何将第二个字典保存到用户默认值并从那里读取?

谢谢

编辑:

这是ebby94推荐的答案:

var myDict = [String:String]()
myDict["key"] = "value";

let data = NSKeyedArchiver.archivedData(withRootObject: myDict)
UserDefaults.standard.set(data, forKey: "myDict")


func foo()

{
  guard let archivedData = UserDefaults.standard.value(forKey: "myDict") as? Data
    else
    {
        print("failed1")
        return
    }
  guard var unarchivedDictionary = NSKeyedUnarchiver.unarchiveObject(with: archivedData) as? [String:String]
    else
    {
        print("failed2")
        return
    }

    print(unarchivedDictionary["key"]!)
}

foo()

但是打印失败1,我假设数据没有正确归档。这可能是因为我 运行 它在操场上吗?

您不能直接在 UserDefaults 中保存字典。您必须将字典转换为数据并保存,然后检索数据并将其取消存档到字典中。

存档并保存到 UserDefaults

    let myDict = [String:String]()
    let data = NSKeyedArchiver.archivedData(withRootObject: myDict)
    UserDefaults.standard.set(data, forKey: "myDict")

检索数据并将数据解档到字典

    guard let archivedData = UserDefaults.standard.value(forKey: "myDict") as? Data
        else{return}
    guard let unarchivedDictionary = NSKeyedUnarchiver.unarchiveObject(with: archivedData) as? [String:String]
        else{return}

用户默认值在 Playground 中不起作用。您需要在模拟器中的应用程序中实施并启动它

如果您想先将自定义对象保存到 userDefault,您需要先对变量进行编码和解码,然后使用存档保存并使用取消存档获取数据。

class Car {
    var engineSize: Int
    var color: String

    init() {
        engineSize = 2000
        color = "blue"
    }
    // Decode
    required convenience public init(coder decoder: NSCoder)
    {
        self.init()

        if let engineSize = decoder.decodeObject(forKey: "engineSize") as? Int
        {
            self.engineSize = engineSize
        }
        if let color = decoder.decodeObject(forKey: "color") as? String
        {
            self.color = color
        }
    }

    // Encode
    func encodeWithCoder(coder : NSCoder)
    {
        if let engineSize = self.engineSize
        {
            coder.encode(engineSize, forKey: "engineSize")
        }
        if let color = self.color
        {
            coder.encode(color, forKey: "weight")
        }
    }
}

class Boat {
    var surfaceArea: Int
    var weight: Int

    init() {
        surfaceArea = 3500
        weight = 4000
    }

    // Decode
    required convenience public init(coder decoder: NSCoder)
    {
        self.init()

        if let surfaceArea = decoder.decodeObject(forKey: "surfaceArea") as? Int
        {
            self.surfaceArea = surfaceArea
        }
        if let weight = decoder.decodeObject(forKey: "weight") as? Int
        {
            self.weight = weight
        }
    }

    // Encode
    func encodeWithCoder(coder : NSCoder)
    {
        if let surfaceArea = self.surfaceArea
        {
            coder.encode(surfaceArea, forKey: "surfaceArea")
        }
        if let weight = self.weight
        {
            coder.encode(weight, forKey: "weight")
        }
    }