使用swift将嵌套的JSON嵌套到嵌套字典中

时间:2017-07-19 14:40:32

标签: json swift dictionary nsjsonserialization codable

我使用新的Codable协议将结构转换为JSON,然后转换为字典以进行测试。问题是结构中的字典变量没有被转换回来并保持Any而不是[Int: String]

struct Person: Codable {
    var name: String?
    var history: [Int: String]

    init() {
        self.name = "Name"
        history = [0: "Test"]
    }
}

let person = Person()

let jsonData = try JSONEncoder().encode(person)

let result = try JSONSerialization.jsonObject(with: jsonData, options: [])

let dictionary = result as? [String: Any]

print(dictionary)

这给了我以下结果

Optional(["history": {
    0 = Test;
}, "name": Name])

我希望

Optional(["history":[0: "Test"]], "name": "Test"])

我很感激为什么会发生这种情况的解释,或者更好的解释如何基本上进行深度JSON序列化。

我正在添加一个展示问题的游乐场: https://www.dropbox.com/s/igpntk7az0hevze/JSONSerialisation.playground.zip

2 个答案:

答案 0 :(得分:1)

当您使用JSONEncoder进行编码时,您还可以使用JSONDecoder来解码json数据。在这种情况下,history是一个不是默认类型之一的字典,因此添加init(from decoder: Decoder)和自定义将是解决预期字典的工作。

struct Person: Codable {
    var name: String
    var history: [Int: String]

    init() {
        self.name = "Name"
        history = [0: "Test"]
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.name = try container.decodeIfPresent(String.self, forKey: .name) ?? "Failed to decode name"
        self.history = try container.decodeIfPresent([Int: String].self, forKey: .history) ?? [-1: "Failed to decode history"]
    }
}

let person = Person()
do {
    let jsonData = try JSONEncoder().encode(person)

    if let result = try? JSONDecoder().decode(Person.self, from: jsonData) {
        print(result)
    }
} catch {
    print(error.localizedDescription)    
}

答案 1 :(得分:0)

原来它是一本字典,只是打印就好像它不是一本。我之所以认为它不是字典,是因为打电话

let history = dictionary["history"] as? [Int: String] 

会导致nil,但原因是JSON显然无法处理[Int: String]。相反,我的[Int: String]已被转换(可能由JSONSerialization.jsonObject(with: jsonData, options: [])函数转换为[String: Any]

let history = dictionary["history"] as? [String: String]

工作正常。

我仍然不明白为什么控制台的打印方式与大括号一样,可能是一个错误?