问题描述
我有以下JSON
数据:
{
"cities": [
{
"id": 1,"name": "Paris","country_code": "FR","attractions": [
"CityHall","Theatre","Port"
],"population": 0
},{
"id": 2,"name": "Nice","attractions": [
"CityHall"
],{
"id": 3,"name": "Berlin","country_code": "DE","attractions": [
"Theatre",{
"id": 4,"name": "Munich","attractions": [
"Theatre"
],{
"id": 5,"name": "Amsterdam","country_code": "NL",{
"id": 6,"name": "Leiden","attractions": [
"CItyHall","Theatre"
],"population": 0
}
]
}
我正在使用对象使用Moya .request(.getCities).map([City].self,atKeyPath: "cities")
对其进行解码:
struct City {
let id: Int
let name: String
let countryCode: String
//let attractions: [Attraction]
let population: Int
}
extension City: Decodable {
enum CodingKeys: String,CodingKey {
case id = "id"
case name = "name"
case countryCode = "countryCode"
//case attractions = "attractions"
case population = "population"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self,forKey: .id)
name = try container.decode(String.self,forKey: .name)
countryCode = try container.decode(String.self,forKey: .countryCode)
//attractions = try container.decode([Attraction].self,forKey: .attractions)
population = try container.decode(Int.self,forKey: .population)
}
}
简单漂亮,但问题是我无法弄清楚如何将attractions
数组放入此处。我将其作为enum
,并尝试使用codingPath
enum Attraction: String {
case CityHall
case Theatre
case Port
}
extension Attraction: Decodable {
enum CodingKeys: String,CodingKey {
// confusion mode initiated :) do I use it the same as in struct here?
case cityHall = "CityHall"
case theatre = "Theatre"
case port = "Port"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let attraction = container.codingPath.first!.stringValue // that would get the first key into string but how to deal with enum?
}
}
此外,如果这样做可以很好地解码attractions
,那么City
对象是否可以对嵌套的对象/数组进行解码?
解决方法
简单漂亮
不,简单而漂亮
struct Root : Decodable {
let cities : [City]
}
struct City : Decodable {
let id: Int
let name: String
let countryCode: String
let atractions: [Attraction] // note the misspelling
let population: Int
}
enum Attraction: String,Decodable {
case cityHall = "CityHall",theatre = "Theatre",port = "Port"
}
let data = Data(jsonString.utf8)
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Root.self,from: data)
print(result.cities)
} catch {
print(error)
}