Search code examples
jsonswiftstructdecodable

parsing json with dynamic keys


I have been working on this for a few hours and have not been able to find an answer. I have a JSON with dynamic keys that I am trying to parse into a struct. I thought I could keep it simple but I'm getting serialization errors. Please help - thanks

{"rates":{
   "btc":{"name":"Bitcoin","unit":"BTC","value":1.0,"type":"crypto"},
   "eth":{"name":"Ether","unit":"ETH","value":35.69,"type":"crypto"},
}}

my stuct

struct CryptoCoins: Decodable {
   let rates: [String: [Coin]]
}

struct Coin: Decodable {
   let name: String
   let unit: String
   let value: Double
   let type: String
}

my decoder:

guard let container = try? JSONDecoder().decode(CryptoCoins.self, from: json) else {
   completion(.failure(.serializationError))  // <- failing here
   return
}

Solution

  • You're decoding the property rates into the wrong type - it's not a dictionary of String keys and an array of Coin values - it's just a single Coin value.

    struct CryptoCoins: Decodable {
       let rates: [String: Coin] // <- here
    }
    

    On a related note, don't hide the error with try?. Capture it and log it, if necessary:

    do {
       let cryptoCoins = try JSONDecoder().decode(CryptoCoins.self, from: json)
       // ..
    } catch {
       print(error)
    }
    

    Then you would have gotten a typeMismatch error for btc key: "Expected to decode Array<Any> but found a dictionary instead.", which would have at least given you a hint of where to look.