在 Decodable 解码函数中检索 JSON 字符串

Retrieving JSON String in Decodable decode function

在解码符合Decodable的ClassA时,我想获取其中一个属性的值来自定义解码。我该如何实现?

class ClassA: Decodable {

    let title: String?
    let data: MyCustomNotDecodableNSObject?

    private enum CodingKeys: String, CodingKey {
        case title
        case data
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        title = try? container.decode(String.self, forKey: .title)

        let dataRawValue = ? // somehow retrieve the raw value that coresponds to the key "data" (JSON string)
        let theData = MyCustomNotDecodableNSObject(rawData: dataRawValue)
        data = theData
    }
}

解析示例 JSON:

{
    "classA" : {
         "title" = "a title"
         "data" : {
             "key1" : "value 1",
             "key2" : "value 2",
             "key3" : "value 3"
          }
} 

我追求的是:

"key1" : "value 1",
"key2" : "value 2",
"key3" : "value 3"

请不要建议让 MyCustomNotDecodableNSObject 符合 Decodable 协议。这个class不能修改

做起来有点困难。我发现的一种方法是首先使用此 中描述的方法将您想要的部分解码为 [String: Any]。然后,使用 JSONSerialization 将该字典转换为 Data,这是一种相当 long-winded 的处理方式,但我找不到更好的方法。

if let dict = try container.decodeIfPresent([String: Any].self, forKey: .data) {
    let dataRawValue = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted) // prettyPrinted is optional here
    data = MyCustomNotDecodableNSObject(rawData: dataRawValue)
} else {
    data = nil
}

如果你真的想要一个 String 传递给 MyCustomNotDecodableNSObject.init,只需调用 String.init(data:encoding:).

需要链接 post 的扩展!