你好,我想解码这个json。
"interest_point":{
"id": 2,
"name": "Panoramic",
"description": "On vous propose ....",
"pointable_type": "ConferenceInterestPoint",
"pointable_id": 1,
"working_time": [],
"pointable": {
"id": 1,
"surface": 354.56,
"capacity": "140",
"price": 500,
"price_unit": "HOURS",
},
"comments": [],
}
"interest_point":{
"id": 5,
"name": "Carte",
"description": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"pointable_type": "RestaurantInterestPoint",
"pointable_id": 2,
"working_time": [],
"pointable": {
"id": 2,
"type": "CARTE",
"smocking_area": 1,
},
"comments": []
}
“ pointable”字段是interest_point的子类,其类型取决于“ pointable_type”。我想动态地将响应解码为InterestPoint的良好ChildType
答案 0 :(得分:0)
也许您有以下类描述了JSON的根:
rect
据我猜测,您有final class Root: Codable {
let interestPoint: InterestPoint?
private enum CodingKeys: String, CodingKey {
case interestPoint = "interest_point"
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
interestPoint = try values.decodeIfPresent(InterestPoint.self, forKey: .interestPoint)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(interestPoint, forKey: .interestPoint)
}
}
作为BaseInterestPoint
,InterestPoint
和ConferenceInterestPoint
的基类:
RestaurantInterestPoint
class BaseInterestPoint: Codable {
let id: Int?
private enum CodingKeys: String, CodingKey {
case id
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(Int.self, forKey: .id)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
}
}
和ConferenceInterestPoint
:
RestaurantInterestPoint
要解决多态对象的问题,请使用enum:
final class ConferenceInterestPoint: BaseInterestPoint {
let surface: Double?
let capacity: String?
let price: Int?
let priceUnit: String?
private enum CodingKeys: String, CodingKey {
case surface
case capacity
case price
case priceUnit = "price_unit"
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
surface = try values.decodeIfPresent(Double.self, forKey: .surface)
capacity = try values.decodeIfPresent(String.self, forKey: .capacity)
price = try values.decodeIfPresent(Int.self, forKey: .price)
priceUnit = try values.decodeIfPresent(String.self, forKey: .priceUnit)
try super.init(from: decoder)
}
override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(surface, forKey: .surface)
try container.encode(capacity, forKey: .capacity)
try container.encode(price, forKey: .price)
try container.encode(priceUnit, forKey: .priceUnit)
}
}
final class RestaurantInterestPoint: BaseInterestPoint {
let type: String?
let smockingArea: Int?
private enum CodingKeys: String, CodingKey {
case type
case smockingArea = "smocking_area"
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
type = try values.decodeIfPresent(String.self, forKey: .type)
smockingArea = try values.decodeIfPresent(Int.self, forKey: .smockingArea)
try super.init(from: decoder)
}
override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(type, forKey: .type)
try container.encode(smockingArea, forKey: .smockingArea)
}
}
在这种情况下,您将获得以下enum Pointable {
case conferenceInterestPoint(ConferenceInterestPoint?)
case restaurantInterestPoint(RestaurantInterestPoint?)
}
:
InterestPoint