JSONDecoder - 解码字符串值以纠正类型
JSONDecoder - decoding string values to correct types
我正在使用一个 JSON api returns 每个字段作为一个字符串。然而,其中一些字符串值实际上表示时间戳以及经度和纬度(作为单独的字段)。
如果我将这些值分别指定为 Date
和 Double
,它 swift 会抛出错误 Expected to decode Double but found a string
Struct Place {
var created_at: Date?
var longitude: Double?
var latitude: Double?
}
我在网上看到了一些似乎处理日期格式的示例,但我不确定如何处理 Double 值?
我尝试覆盖 init(from decoder:Decoder)
但这仍然没有给出正确的值:
例如
init(from decoder:Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
longitude = try values.decode(Double.self, forKey: .longitude) //returns nil but using String works fine
}
我知道我可以提取字符串并转换为双精度值,例如:
longitude = Double(try values.decode(String.self, forKey: .longitude))
但是还有别的办法吗?
此外,我实际上还有许多其他属性可以很好地转换,但是通过对这 3 个属性进行此工作,我现在必须在其中添加所有其他属性,这似乎有点多余。有更好的方法吗?
如果 JSON 值为 String
,则必须解码 String
。从 String
到 Double
的隐式类型转换是不可能的。
您可以通过添加计算变量 coordinate
来避免自定义初始化程序,在这种情况下需要 CodingKeys
import CoreLocation
struct Place : Decodable {
private enum CodingKeys: String, CodingKey { case createdAt = "created_at", longitude, latitude}
let createdAt: Date
let longitude: String
let latitude: String
var coordinate : CLLocationCoordinate2D {
return CLLocationCoordinate2D(latitude: Double(latitude) ?? 0.0, longitude: Double(longitude) ?? 0.0)
}
}
我正在使用一个 JSON api returns 每个字段作为一个字符串。然而,其中一些字符串值实际上表示时间戳以及经度和纬度(作为单独的字段)。
如果我将这些值分别指定为 Date
和 Double
,它 swift 会抛出错误 Expected to decode Double but found a string
Struct Place {
var created_at: Date?
var longitude: Double?
var latitude: Double?
}
我在网上看到了一些似乎处理日期格式的示例,但我不确定如何处理 Double 值?
我尝试覆盖 init(from decoder:Decoder)
但这仍然没有给出正确的值:
例如
init(from decoder:Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
longitude = try values.decode(Double.self, forKey: .longitude) //returns nil but using String works fine
}
我知道我可以提取字符串并转换为双精度值,例如:
longitude = Double(try values.decode(String.self, forKey: .longitude))
但是还有别的办法吗?
此外,我实际上还有许多其他属性可以很好地转换,但是通过对这 3 个属性进行此工作,我现在必须在其中添加所有其他属性,这似乎有点多余。有更好的方法吗?
如果 JSON 值为 String
,则必须解码 String
。从 String
到 Double
的隐式类型转换是不可能的。
您可以通过添加计算变量 coordinate
来避免自定义初始化程序,在这种情况下需要 CodingKeys
import CoreLocation
struct Place : Decodable {
private enum CodingKeys: String, CodingKey { case createdAt = "created_at", longitude, latitude}
let createdAt: Date
let longitude: String
let latitude: String
var coordinate : CLLocationCoordinate2D {
return CLLocationCoordinate2D(latitude: Double(latitude) ?? 0.0, longitude: Double(longitude) ?? 0.0)
}
}