Search code examples
iosjsonswiftjsondecoder

JSON Decode of Arrays and Dictionaries in Swift Model


For some reason, I can't seem to decode the following JSON from an API, probably because my model is not right for the JSON:

{"definitions":[{"type":"noun","definition":"the larva of a 
butterfly.","example":null,"image_url":null,"emoji":null},
{"type":"adjective","definition":"brand of heavy equipment.","example":null,"image_url":null,"emoji":null}],
"word":"caterpillar","pronunciation":"ˈkadə(r)ˌpilər"}

Here is my model:

struct DefinitionReturned : Codable {
        let Definition : [Definition]
        let word : String
        let pronunciation : String

    }
    struct Definition : Codable {
        let type: String
        let definition: String
        let example: String?
        let image_url: String?
        let emoji : String?
    }

The code to decode is:

let json = try? JSONSerialization.jsonObject(with: data, options: [])

                do {

                    let somedefinitions = try JSONDecoder().decode(DefinitionReturned.self, from: data)
                    print("here are the definitions",somedefinitions)
}

The error is:

ERROR IN DECODING DATA
The data couldn’t be read because it is missing.
keyNotFound(CodingKeys(stringValue: "Definition", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"Definition\", intValue: nil) (\"Definition\").", underlyingError: nil))

Of note, there can be one or more definitions.

What am I doing wrong?


Solution

  • // MARK: - DefinitionReturned
    struct DefinitionReturned: Codable {
        let definitions: [Definition]
        let word, pronunciation: String
    }
    
    // MARK: - Definition
    struct Definition: Codable {
        let type, definition: String
        let example, imageURL, emoji: String?
    
        enum CodingKeys: String, CodingKey {
            case type, definition, example
            case imageURL = "image_url"
            case emoji
        }
    }
    

    Then decode

    let definitionReturned = try? JSONDecoder().decode(DefinitionReturned.self, from: jsonData)