Search code examples
jsonswiftdecoder

Swift json decode with dynamic keys


i'm trying to decode a nested json with dynamic keys, but can't find a solution. here's my json:

{
    "available_channels": {
        "1000": {
            "creation_date": "1111222",
            "category_id": "9"
        },
        "1001": {
            "creation_date": "222333",
            "category_id": "10"
        }
}

as you can see, "1000" and "1001" are dynamique.

The models i'm using:

struct StreamsData: Codable{
    let availableChannels: AvailableChannels
}

struct AvailableChannels: Codable{
    let channels: [String: Channel]
}

struct Channel: Codable{
    let creationDate: String
    let categoryId: String
}

'StreamsData' is the root object

'AvailableChannels' is the objects containing all channels objects

'Channel' channel model

decoding the json:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let streams = try decoder.decode(StreamsData.self, from: data)

With this code i have this error:

CodingKeys(stringValue: "availableChannels", intValue: nil) - debugDescription : "No value associated with key CodingKeys(stringValue: \"channels\", intValue: nil) (\"channels\")."

The problem is clear, as 'AvailableChannels' is declared to have a 'channel' property, the decoder is trying to find "channels" as key for the object containing the "creation_date".

Could you help me to solve this problem, thanks.


Solution

  • You only need

    struct StreamsData: Codable{
        let availableChannels: [String: Channel]
    }
    
    struct Channel: Codable{
        let creationDate,categoryId: String 
    }
    

    do {
        let dec = JSONDecoder()
        dec.keyDecodingStrategy = .convertFromSnakeCase
        let res = try dec.decode(StreamsData.self, from: data)
    }
    catch { 
        print(error)
    }