How can I parse this JSON in Swift?
This JSON is from an API, and the API provider explained the JSON’s "data" object like this.
Screenshot of the description.
The problem is that the JSON Decoder can’t decode the JSON at all. Its error message is "type mismatch".
{
"meta": {
"last_updated_at": "2023-02-15T12:59:59Z"
},
"data": {
"ADA": {
"code": "ADA",
"value": 0.001978
},
"AED": {
"code": "AED",
"value": 0.002859
},
"AFN": {
"code": "AFN",
"value": 0.0696
},
"ALL": {
"code": "ALL",
"value": 0.084096
},
"AMD": {
"code": "AMD",
"value": 0.306311
},
"ANG": {
"code": "ANG",
"value": 0.001403
},
"AOA": {
"code": "AOA",
"value": 0.392615
},
"ARS": {
"code": "ARS",
"value": 0.149368
},
"AUD": {
"code": "AUD",
"value": 0.00113
},
"AVAX": {
"code": "AVAX",
"value": 4.2e-5
},
"AWG": {
"code": "AWG",
"value": 0.001403
},
"AZN": {
"code": "AZN",
"value": 0.001323
},
"BAM": {
"code": "BAM",
"value": 0.001421
},
"BBD": {
"code": "BBD",
"value": 0.001572
},
"BDT": {
"code": "BDT",
"value": 0.082699
},
"BGN": {
"code": "BGN",
"value": 0.00142
},
"BHD": {
"code": "BHD",
"value": 0.000293
},
"BIF": {
"code": "BIF",
"value": 1.616223
},
"BMD": {
"code": "BMD",
"value": 0.000778
},
"BNB": {
"code": "BNB",
"value": 3.0e-6
},
"BND": {
"code": "BND",
"value": 0.001039
},
"BOB": {
"code": "BOB",
"value": 0.005378
},
"BRL": {
"code": "BRL",
"value": 0.004062
},
"BSD": {
"code": "BSD",
"value": 0.000778
},
"BTC": {
"code": "BTC",
"value": 0
},
"BTN": {
"code": "BTN",
"value": 0.064445
},
"BWP": {
"code": "BWP",
"value": 0.010201
},
"BYN": {
"code": "BYN",
"value": 0.001965
},
"BYR": {
"code": "BYR",
"value": 15.257164
},
"BZD": {
"code": "BZD",
"value": 0.001569
},
"CAD": {
"code": "CAD",
"value": 0.001044
},
"CDF": {
"code": "CDF",
"value": 1.591884
},
"CHF": {
"code": "CHF",
"value": 0.000718
},
"CLF": {
"code": "CLF",
"value": 2.2e-5
},
"CLP": {
"code": "CLP",
"value": 0.614919
},
"CNY": {
"code": "CNY",
"value": 0.005326
},
"COP": {
"code": "COP",
"value": 3.698284
},
"CRC": {
"code": "CRC",
"value": 0.442391
},
"CUC": {
"code": "CUC",
"value": 0.000782
},
"CUP": {
"code": "CUP",
"value": 0.01868
},
"CVE": {
"code": "CVE",
"value": 0.080125
},
"CZK": {
"code": "CZK",
"value": 0.017217
},
"DJF": {
"code": "DJF",
"value": 0.138581
},
"DKK": {
"code": "DKK",
"value": 0.005422
},
"DOP": {
"code": "DOP",
"value": 0.043735
},
"DOT": {
"code": "DOT",
"value": 0.000123
},
"DZD": {
"code": "DZD",
"value": 0.106398
},
"EGP": {
"code": "EGP",
"value": 0.023798
},
"ERN": {
"code": "ERN",
"value": 0.011676
},
"ETB": {
"code": "ETB",
"value": 0.041827
},
"ETH": {
"code": "ETH",
"value": 0
},
"EUR": {
"code": "EUR",
"value": 0.000728
},
"FJD": {
"code": "FJD",
"value": 0.001706
},
"FKP": {
"code": "FKP",
"value": 0.000647
},
"GBP": {
"code": "GBP",
"value": 0.000646
},
"GEL": {
"code": "GEL",
"value": 0.002067
},
"GGP": {
"code": "GGP",
"value": 0.000647
},
"GHS": {
"code": "GHS",
"value": 0.009632
},
"GIP": {
"code": "GIP",
"value": 0.000647
},
"GMD": {
"code": "GMD",
"value": 0.047601
},
"GNF": {
"code": "GNF",
"value": 6.70225
},
"GTQ": {
"code": "GTQ",
"value": 0.006094
},
"GYD": {
"code": "GYD",
"value": 0.164233
},
"HKD": {
"code": "HKD",
"value": 0.00611
},
"HNL": {
"code": "HNL",
"value": 0.019186
},
"HTG": {
"code": "HTG",
"value": 0.116942
},
"HUF": {
"code": "HUF",
"value": 0.276597
},
"IDR": {
"code": "IDR",
"value": 11.864333
},
"ILS": {
"code": "ILS",
"value": 0.002746
},
"IMP": {
"code": "IMP",
"value": 0.000647
},
"INR": {
"code": "INR",
"value": 0.064507
},
"IQD": {
"code": "IQD",
"value": 1.135978
},
"IRR": {
"code": "IRR",
"value": 32.888583
},
"ISK": {
"code": "ISK",
"value": 0.111985
},
"JEP": {
"code": "JEP",
"value": 0.000647
},
"JMD": {
"code": "JMD",
"value": 0.120157
},
"JOD": {
"code": "JOD",
"value": 0.000553
},
"JPY": {
"code": "JPY",
"value": 0.10407
},
"KES": {
"code": "KES",
"value": 0.097763
},
"KGS": {
"code": "KGS",
"value": 0.0677
},
"KHR": {
"code": "KHR",
"value": 3.180334
},
"KMF": {
"code": "KMF",
"value": 0.357201
},
"KPW": {
"code": "KPW",
"value": 0.70051
},
"KRW": {
"code": "KRW",
"value": 1
},
"KWD": {
"code": "KWD",
"value": 0.000238
},
"KYD": {
"code": "KYD",
"value": 0.000649
},
"KZT": {
"code": "KZT",
"value": 0.347961
},
"LAK": {
"code": "LAK",
"value": 13.112856
},
"LBP": {
"code": "LBP",
"value": 11.682782
},
"LKR": {
"code": "LKR",
"value": 0.284092
},
"LRD": {
"code": "LRD",
"value": 0.122369
},
"LSL": {
"code": "LSL",
"value": 0.013942
},
"LTC": {
"code": "LTC",
"value": 8.0e-6
},
"LTL": {
"code": "LTL",
"value": 0.002298
},
"LVL": {
"code": "LVL",
"value": 0.000471
},
"LYD": {
"code": "LYD",
"value": 0.00373
},
"MAD": {
"code": "MAD",
"value": 0.008016
},
"MATIC": {
"code": "MATIC",
"value": 0.000611
},
"MDL": {
"code": "MDL",
"value": 0.014574
},
"MGA": {
"code": "MGA",
"value": 3.340641
},
"MKD": {
"code": "MKD",
"value": 0.044773
},
"MMK": {
"code": "MMK",
"value": 1.634501
},
"MNT": {
"code": "MNT",
"value": 2.741876
},
"MOP": {
"code": "MOP",
"value": 0.006292
},
"MRO": {
"code": "MRO",
"value": 0.277898
},
"MUR": {
"code": "MUR",
"value": 0.035605
},
"MVR": {
"code": "MVR",
"value": 0.011949
},
"MWK": {
"code": "MWK",
"value": 0.798893
},
"MXN": {
"code": "MXN",
"value": 0.014527
},
"MYR": {
"code": "MYR",
"value": 0.003419
},
"MZN": {
"code": "MZN",
"value": 0.049119
},
"NAD": {
"code": "NAD",
"value": 0.013942
},
"NGN": {
"code": "NGN",
"value": 0.358513
},
"NIO": {
"code": "NIO",
"value": 0.028441
},
"NOK": {
"code": "NOK",
"value": 0.007938
},
"NPR": {
"code": "NPR",
"value": 0.103111
},
"NZD": {
"code": "NZD",
"value": 0.001241
},
"OMR": {
"code": "OMR",
"value": 0.0003
},
"PAB": {
"code": "PAB",
"value": 0.000778
},
"PEN": {
"code": "PEN",
"value": 0.002993
},
"PGK": {
"code": "PGK",
"value": 0.002743
},
"PHP": {
"code": "PHP",
"value": 0.043029
},
"PKR": {
"code": "PKR",
"value": 0.20645
},
"PLN": {
"code": "PLN",
"value": 0.003466
},
"PYG": {
"code": "PYG",
"value": 5.665336
},
"QAR": {
"code": "QAR",
"value": 0.002834
},
"RON": {
"code": "RON",
"value": 0.003566
},
"RSD": {
"code": "RSD",
"value": 0.085355
},
"RUB": {
"code": "RUB",
"value": 0.057807
},
"RWF": {
"code": "RWF",
"value": 0.845186
},
"SAR": {
"code": "SAR",
"value": 0.00292
},
"SBD": {
"code": "SBD",
"value": 0.006392
},
"SCR": {
"code": "SCR",
"value": 0.010389
},
"SDG": {
"code": "SDG",
"value": 0.454602
},
"SEK": {
"code": "SEK",
"value": 0.008098
},
"SGD": {
"code": "SGD",
"value": 0.001039
},
"SHP": {
"code": "SHP",
"value": 0.000947
},
"SLL": {
"code": "SLL",
"value": 15.373958
},
"SOL": {
"code": "SOL",
"value": 3.5e-5
},
"SOS": {
"code": "SOS",
"value": 0.443315
},
"SRD": {
"code": "SRD",
"value": 0.02528
},
"STD": {
"code": "STD",
"value": 16.111862
},
"SVC": {
"code": "SVC",
"value": 0.00681
},
"SYP": {
"code": "SYP",
"value": 1.955824
},
"SZL": {
"code": "SZL",
"value": 0.013994
},
"THB": {
"code": "THB",
"value": 0.026762
},
"TJS": {
"code": "TJS",
"value": 0.008126
},
"TMT": {
"code": "TMT",
"value": 0.002724
},
"TND": {
"code": "TND",
"value": 0.00243
},
"TOP": {
"code": "TOP",
"value": 0.001815
},
"TRY": {
"code": "TRY",
"value": 0.014672
},
"TTD": {
"code": "TTD",
"value": 0.005282
},
"TWD": {
"code": "TWD",
"value": 0.023579
},
"TZS": {
"code": "TZS",
"value": 1.820522
},
"UAH": {
"code": "UAH",
"value": 0.028745
},
"UGX": {
"code": "UGX",
"value": 2.856504
},
"USD": {
"code": "USD",
"value": 0.000778
},
"UYU": {
"code": "UYU",
"value": 0.030382
},
"UZS": {
"code": "UZS",
"value": 8.848938
},
"VEF": {
"code": "VEF",
"value": 1883.620605
},
"VND": {
"code": "VND",
"value": 18.390362
},
"VUV": {
"code": "VUV",
"value": 0.090749
},
"WST": {
"code": "WST",
"value": 0.002115
},
"XAF": {
"code": "XAF",
"value": 0.476658
},
"XAG": {
"code": "XAG",
"value": 3.6e-5
},
"XAU": {
"code": "XAU",
"value": 0
},
"XCD": {
"code": "XCD",
"value": 0.002104
},
"XDR": {
"code": "XDR",
"value": 0.00058
},
"XOF": {
"code": "XOF",
"value": 0.476658
},
"XPF": {
"code": "XPF",
"value": 0.086911
},
"XRP": {
"code": "XRP",
"value": 0.001996
},
"YER": {
"code": "YER",
"value": 0.194841
},
"ZAR": {
"code": "ZAR",
"value": 0.014003
},
"ZMK": {
"code": "ZMK",
"value": 7.006775
},
"ZMW": {
"code": "ZMW",
"value": 0.015041
},
"ZWL": {
"code": "ZWL",
"value": 0.250653
}
}
}
I used the model below to decode the JSON above.
import Foundation
struct CurrencyAPIResponse_Latest: Codable {
let meta: Meta
let data: [String: Currency]
}
struct Currency: Codable {
let code: String
let value: Float
}
struct Meta: Codable {
let lastUpdatedAt: Date
enum CodingKeys: String, CodingKey {
case lastUpdatedAt = "last_updated_at"
}
}
Honestly, I’m not good at parsing JSON, so I couldn’t even try to fix this error. I just can’t understand why it keeps failing. Any help??
2
Answers
One helpful thing to do is to paste your code, along with JSON (in
"""
quotes to allow multiline pasting) into playground and run it there.So when I do, the error I see is this:
which says pretty clearly where the problem is: you expect
lastUpdatedAt
to be aDate
inbut it’s a string:
So you have 3 options:
Option 1: Set the date decoding strategy for the
JSONDecoder
. Since the format of your date is ISO8601, this will work:Option 2: If you cannot / don’t want to change
JSONDecoder()
‘sdateDecodingStrategy
, you can make a custom conversion:Note that parsing may fail, and for that reason I changed
lastUpdatedAt
to optional. You can change the parsing in a different way.Option 3: Finally, you don’t always need a conversion to happen right away. In that case you can change the model to accept a string, and convert it to date later, when you actually need a date.
Here is an example you could use.
To decode the string or data:
Of course you have to replace
jsonString
orjsonData
. Either with a JSON string, or with the JSON data from the server. 🙂