This is my json I am trying to decode using JSONDecoder but having hard time as its not able to do it. can someone help with what struct and how can I decode?
{
"Afghanistan": [
{
"city": "Kabul",
"lat": "34.5167",
"lng": "69.1833",
"state": "Kābul",
"country": "Afghanistan"
},
{
"city": "Karukh",
"lat": "34.4868",
"lng": "62.5918",
"state": "Herāt",
"country": "Afghanistan"
},
{
"city": "Zarghūn Shahr",
"lat": "32.85",
"lng": "68.4167",
"state": "Paktīkā",
"country": "Afghanistan"
}
],
"Albania": [
{
"city": "Tirana",
"lat": "41.3275",
"lng": "19.8189",
"state": "Tiranë",
"country": "Albania"
},
{
"city": "Pukë",
"lat": "42.0333",
"lng": "19.8833",
"state": "Shkodër",
"country": "Albania"
}
]}
what do you suggest to decode it?
I am trying this
let locationData: Countries = load("Countries.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
struct Country: Codable, Identifiable {
var id = UUID()
let city, lat, lng: String
let state: String?
let country: String
}
typealias Countries = [String: [Country]]
But getting this error
Couldn't parse Countries.json as Dictionary>: keyNotFound(CodingKeys(stringValue: "id", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Albania", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"id\", intValue: nil) (\"id\").", underlyingError: nil)):
fatalError
is usually a bad idea, especially in the catch block of ado-catch
. If you really cannot recover from an error thrown bytry
, you should simply usetry!
. However, in most cases that's a bad idea as well, since if thatcatch
block ever gets executed for a user, the app will simply crash without them getting an error message. It's best to useassertionFailures
instead offatalError
a so that you catch errors early during development, but users never experience crashes and display them a generic error message instead. – Dávid Pásztor