Swift-将字典[String:Any]编码和解码为plist

时间:2018-12-03 00:04:21

标签: swift dictionary encoding nested decode

我正在尝试将字典存储在我的类Marker中,但是抛出错误,指出该字典不可编码或无法解码。我可以看到错误是由[String:Any]引起的,但是如何解决呢?

var buttonActions : [String: [String: [String:Any]]] = [:]

保存并加载

func saveData() {
    let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("\(fileName).plist")

    let encoder = PropertyListEncoder()
    do {
        let data = try encoder.encode(markerArray)
        try data.write(to: dataFilePath!)
        print("Saved")
    } catch {
        print("Error Encoding \(error)")
    }
}

func loadData() {
    let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("\(fileName).plist")

    if let data = try? Data(contentsOf: dataFilePath!){
        let decoder = PropertyListDecoder()
        do {
            markerArray = try decoder.decode([Marker].self, from: data)
        } catch {
            print("Decode Error \(error)")
        }
    }

班级

class Marker : Encodable, Decodable {
    var UUIDpic: UUID = UUID()
    var alpha: Int = 1
    var buttonType: Int = 0
    var buttonActions : [String: [String: [String:Any]]] = [:]
    var buttonNameColor: String = ""
    var buttonNameFontSize: Int = 10
    var buttonShape: String = ""
    var loggerRect: String = ""
    var maskColor: String = ""
    var name: String = ""
}

2 个答案:

答案 0 :(得分:4)

很遗憾,您不能在包含encode的通用类型(例如decodeAny)上使用[String: Any][Any]Any不符合协议Encodable也不符合Decodable,并且Swift不知道如何对其进行编码/解码。您必须为字典使用具体的通用类型(例如[String: String])。

如果仍然需要使用Any之类的常规类型,则必须实现encode(to:)init(from:)方法。另一种选择是使用struct代替符合[String: [String: [String:Any]]]Codable)的Encodable & Decodable。您仍将必须在该结构中实现encode(to:)init(from:)方法,但好的一面是,您将不必为所有属性编写encoder.encode()故事如果您在Marker类中实现它们。

答案 1 :(得分:1)

所以终于在Andrada的帮助下解决了这个问题。

我添加了第二个结构来保存动作,并通过必须使用[string:any]

class Marker : Encodable, Decodable {
var UUIDpic: UUID = UUID()
var alpha: Int = 1
var buttonType: Int = 0
var buttonAction : [String: [ButtonAction]] = [:] //Dictionary I edited using the new struct
var buttonNameColor: String = ""
var buttonNameFontSize: Int = 10
var buttonShape: String = ""
var loggerRect: String = ""
var maskColor: String = ""
var name: String = ""
}

下面是我添加的结构

struct ButtonAction: Codable {
var action: String
var array_linked_of_buttons: [[String:String]]

init(action: String, array_linked_of_buttons: [[String:String]]) {
 self.action = action
 self.array_linked_of_buttons = array_linked_of_buttons
    }
}

请确保初始化您的结构,否则它将不起作用。