将Swift中的不同JSON提要解析为相同的可解码结构
我有两个不同的JSON提要将Swift中的不同JSON提要解析为相同的可解码结构,json,swift,decodable,Json,Swift,Decodable,我有两个不同的JSON提要 { "uid":9018823, "lat":43.25394, "lng":-2.93844, "bike":false, "name":"02-STATION", "address":null, "spot":true, "number":3388, "bikes":3, "booked_bikes":0, "bike_racks":20, "free_racks":16 } 及 我想要的是解析填充以下结构的两个提要 struct Pl
{
"uid":9018823,
"lat":43.25394,
"lng":-2.93844,
"bike":false,
"name":"02-STATION",
"address":null,
"spot":true,
"number":3388,
"bikes":3,
"booked_bikes":0,
"bike_racks":20,
"free_racks":16
}
及
我想要的是解析填充以下结构的两个提要
struct Places: Codable {
var name: String
let lat: Double
let lng: Double
}
正如我所看到的,我可以使用
init中的Decodable
实现这一点(来自解码器:解码器)
但我不能把我的头绕在它周围,让它工作。解决这一问题的一种方法是为每个json消息类型设置一个CodingKey枚举,然后在尝试使用一个枚举创建容器时,我们会捕获任何错误,而不是抛出它,并尝试使用另一个枚举创建容器
struct Places: Decodable {
let name: String
let lat: Double
let lng: Double
enum CodingKeys1: String, CodingKey {
case name
case lat
case lng
}
enum CodingKeys2: String, CodingKey {
case name = "station_name"
case lat = "latitude"
case lng = "longitude"
}
init(from decoder: Decoder) throws {
do {
let container = try decoder.container(keyedBy: CodingKeys1.self)
try self.init(container)
} catch {
let container = try decoder.container(keyedBy: CodingKeys2.self)
try self.init(container)
}
}
private init(_ container: KeyedDecodingContainer<CodingKeys1>) throws {
name = try container.decode(String.self, forKey: .name)
lat = try container.decode(Double.self, forKey: .lat)
lng = try container.decode(Double.self, forKey: .lng)
}
private init(_ container: KeyedDecodingContainer<CodingKeys2>) throws {
name = try container.decode(String.self, forKey: .name)
lat = try container.decode(Double.self, forKey: .lat)
lng = try container.decode(Double.self, forKey: .lng)
}
}
地点(名称:“02站”,纬度:43.25394,液化天然气:-2.93844)地点(名称:“科菲街和康诺弗街”,lat:40.677236,液化天然气:-74.015665)
对于第二个JSON,您希望
name
具有什么价值?这看起来很有希望,非常感谢您的帮助!
struct Places: Decodable {
let name: String
let lat: Double
let lng: Double
enum CodingKeys1: String, CodingKey {
case name
case lat
case lng
}
enum CodingKeys2: String, CodingKey {
case name = "station_name"
case lat = "latitude"
case lng = "longitude"
}
init(from decoder: Decoder) throws {
do {
let container = try decoder.container(keyedBy: CodingKeys1.self)
try self.init(container)
} catch {
let container = try decoder.container(keyedBy: CodingKeys2.self)
try self.init(container)
}
}
private init(_ container: KeyedDecodingContainer<CodingKeys1>) throws {
name = try container.decode(String.self, forKey: .name)
lat = try container.decode(Double.self, forKey: .lat)
lng = try container.decode(Double.self, forKey: .lng)
}
private init(_ container: KeyedDecodingContainer<CodingKeys2>) throws {
name = try container.decode(String.self, forKey: .name)
lat = try container.decode(Double.self, forKey: .lat)
lng = try container.decode(Double.self, forKey: .lng)
}
}
do {
for data in [data1, data2] {
let result = try JSONDecoder().decode(Places.self, from: data)
print(result)
}
} catch {
print(error)
}