Home > front end >  Swift json decoder with mixed array
Swift json decoder with mixed array

Time:12-30

Looking for help to decode irregular (for a lack of a better word) json. As an example:

[
    {
        "texts":
        [
            {
                "value": "value 1"
            }
        ],
    
        "commentType": "someComment"
    },
    
    {
        "texts":
        [
            {
                "value": "value 2"
            }
        ],
        "commentType": "someComment2"
    },
    
    {
        "texts":
        [
            {
                "evidences": 
                [
                    {
                        "evidenceCode": "code 1",
                    },
                    {
                        "evidenceCode": "code 2",
                    },
                    {
                        "evidenceCode": "code 3",
                    },
                    {
                        "evidenceCode": "code 4",
                    }
                ],
                
                "value": "value 3"
            }
        ],
        "commentType": "someComment3"
    }
]

I can decode comment and the first two "texts":

enum CodingKeys: String, CodingKey {
    case texts
    case commentType
}

do {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    name = try container.decode(String.self, forKey: .commentType)
    
    // TODO:
    if let texts = try container.decodeIfPresent([[String: String]].self, forKey: .texts) {
        for text in texts {
            if let value = text["value"] {
                // add to model object
            }
        }
    }

} catch {
    print(error)
}

But I get an error for the third "texts" block:

"Expected to decode String but found an array instead."

Which I understand, since now instead of an array of [String:String], it is a mixed array of [String:[String:String] and [String:String].

How do I decode value3 from that third block?

CodePudding user response:

Actually this is not complicated at all because the content of texts is the same if we treat evidences as an optional array. The below models will decode the json correctly without any custom code.

struct Result: Decodable {
    var texts: [TextData]
    var commentType: String
}

struct TextData: Decodable {
    let evidences: [Evidence]?
    let value: String
}

struct Evidence: Decodable {
    let evidenceCode: String
}
  • Related