i have problem with my json response
When I use this func , I print all data corect
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let jsonString = String(data: data, encoding: .utf8) {
print(jsonString)
}
}
} .resume()
i get this correct data:
"brand":"Lamborghini", "model":"Huracan", "color":"#0052ff" ,"registration":"K1TEST", "lat":50.244495, "lng":18.996143,
but when i am using JasonDecoder and Model struct
URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
return
}
do {
let decoder = JSONDecoder()
let carData = try decoder.decode([Model].self, from: data)
print(carData)
} catch {
print(error)
}
} .resume()
Model:
struct Model : Codable {
let brand : String
let model : String
let color : String
let registration : String
let lat : Double
let lng : Double }
CodingKeys(stringValue: "lat", intValue: nil)], debugDescription: "Expected to decode Double but found a string/data instead."
I know that this is something wrong whit lat and lng data but i don't know how to fix it. Help
CodePudding user response:
let lat : String
try this. from the error itself we can understand that you are getting lat as string and you are trying to parse as to double. I think the same thing will happen for lng also, so try to parse accordingly
CodePudding user response:
The problem you have identified, where lat
and lng
can be Double
and sometimes String
,
can be dealt with the following code, to decode lat
and lng
into a consistent Double
.
struct Model : Identifiable, Codable, Hashable {
let id: String // <-- an id is very usefull in SwiftUI code
let brand : String
let model : String
let color : String
let registration : String
let lat : Double
let lng : Double
enum CodingKeys: String, CodingKey {
case brand,model,color,registration,lat,lng
case id = "_id"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decode(String.self, forKey: .id)
brand = try values.decode(String.self, forKey: .brand)
model = try values.decode(String.self, forKey: .model)
color = try values.decode(String.self, forKey: .color)
registration = try values.decode(String.self, forKey: .registration)
// decode lat, when it comes as a String
if let theString = try? values.decode(String.self, forKey: .lat),
let latitude = Double(theString) {
lat = latitude
} else {
lat = try values.decode(Double.self, forKey: .lat)
}
// decode lng, when it comes as a String
if let theString = try? values.decode(String.self, forKey: .lng),
let longitude = Double(theString) {
lng = longitude
} else {
lng = try values.decode(Double.self, forKey: .lng)
}
}
}