I'm trying to practice Swift's Codable API. I send a network request and I receive one single line each time as follows where I have to deal with dynamic keys :
Response example 1:
{
"EUR": 4695.01
}
Response example 2:
{
"USD": 479.01
}
Response example 3:
{
"BTC": 4735.01
}
I tried this method to parse the dynamic keys :
struct ConversionResponseModel: Decodable {
typealias destinationCurrency = String
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
}
}
and my fetching request :
do {
let myResult = try JSONDecoder().decode(ConversionResponseModel.self, from: data)
print(myResult)
} catch {
print(error)
}
But I get this as a result : ConversionResponseModel()
, but not the currency values.
It sounds like I'm missing something. Any help please. Thank you
You're almost there. The JSON you're getting will return a dictionary of [String:Double]
. You can then covert that using:
struct ConversionResponseModel: Decodable {
typealias DestinationCurrency = String
let currency : DestinationCurrency
let value : Double
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let dict = try container.decode([String:Double].self)
guard let key = dict.keys.first else {
throw NSError(domain: "Decoder", code: 0, userInfo: [:])
}
currency = key
value = dict[key] ?? -1
}
}
Note: taking into account Rob Napier's comment, you could substitute Decimal
for Double
-- see his comment on the original question for more detail