用户默认值不保存swift 3中的字典内容

时间:2017-01-25 02:37:12

标签: ios swift dictionary nsuserdefaults

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

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 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]()

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

谢谢

修改

这是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,我假设数据没有正确存档。这可能是因为我在操场上跑步吗?

3 个答案:

答案 0 :(得分:3)

如果要首先将自定义对象保存到userDefault,则需要编码&解码变量然后使用存档&使用unarchive获取数据。

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")
        }
    }

答案 1 :(得分:2)

您无法直接在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}

答案 2 :(得分:0)

Userdefaults在Playground中不起作用。您需要在模拟器中的应用程序中实现并启动它