快速解码多态json响应
你好,我想解码这个json快速解码多态json响应,json,inheritance,polymorphism,swift4,codable,Json,Inheritance,Polymorphism,Swift4,Codable,你好,我想解码这个json "interest_point":{ "id": 2, "name": "Panoramic", "description": "On vous propose ....", "pointable_type": "ConferenceInterestPoint", "pointable_id": 1, "working_time": [], "pointable": { "id": 1,
"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": [],
}
“pointable”字段是一个感兴趣的子类,其类型取决于“pointable”类型。我想动态地将响应解码为感兴趣的good ChildType point也许您有以下类描述JSON的根:
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
和restaurantinterespoint
的基类:
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)
}
}
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)
}
}
final class InterestPoint: BaseInterestPoint {
let name: String?
let description: String?
let pointableType: String?
let pointableId: Int?
let workingTime: [Int]?
let pointable: Pointable?
let comments: [String]?
private enum CodingKeys: String, CodingKey {
case name
case description
case pointableType = "pointable_type"
case pointableId = "pointable_id"
case workingTime = "working_time"
case pointable
case comments
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
description = try values.decodeIfPresent(String.self, forKey: .description)
pointableType = try values.decodeIfPresent(String.self, forKey: .pointableType)
pointableId = try values.decodeIfPresent(Int.self, forKey: .pointableId)
workingTime = try values.decodeIfPresent([Int].self, forKey: .workingTime)
if pointableType == "ConferenceInterestPoint" {
pointable = .conferenceInterestPoint(try values.decodeIfPresent(ConferenceInterestPoint.self, forKey: .pointable))
} else if pointableType == "RestaurantInterestPoint" {
pointable = .restaurantInterestPoint(try values.decodeIfPresent(RestaurantInterestPoint.self, forKey: .pointable))
} else {
pointable = nil
}
comments = try values.decodeIfPresent([String].self, forKey: .comments)
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(name, forKey: .name)
try container.encode(description, forKey: .description)
try container.encode(pointableType, forKey: .pointableType)
try container.encode(pointableId, forKey: .pointableId)
try container.encode(workingTime, forKey: .workingTime)
if let pointable = pointable {
switch pointable {
case .conferenceInterestPoint(let conferenceInterestPoint):
if let conferenceInterestPoint = conferenceInterestPoint {
try container.encode(conferenceInterestPoint, forKey: .pointable)
}
case .restaurantInterestPoint(let restaurantInterestPoint):
if let restaurantInterestPoint = restaurantInterestPoint {
try container.encode(restaurantInterestPoint, forKey: .pointable)
}
}
}
try container.encode(comments, forKey: .comments)
}
}
会议兴趣点
和餐厅兴趣点
:
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)
}
}
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)
}
}
final class InterestPoint: BaseInterestPoint {
let name: String?
let description: String?
let pointableType: String?
let pointableId: Int?
let workingTime: [Int]?
let pointable: Pointable?
let comments: [String]?
private enum CodingKeys: String, CodingKey {
case name
case description
case pointableType = "pointable_type"
case pointableId = "pointable_id"
case workingTime = "working_time"
case pointable
case comments
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
description = try values.decodeIfPresent(String.self, forKey: .description)
pointableType = try values.decodeIfPresent(String.self, forKey: .pointableType)
pointableId = try values.decodeIfPresent(Int.self, forKey: .pointableId)
workingTime = try values.decodeIfPresent([Int].self, forKey: .workingTime)
if pointableType == "ConferenceInterestPoint" {
pointable = .conferenceInterestPoint(try values.decodeIfPresent(ConferenceInterestPoint.self, forKey: .pointable))
} else if pointableType == "RestaurantInterestPoint" {
pointable = .restaurantInterestPoint(try values.decodeIfPresent(RestaurantInterestPoint.self, forKey: .pointable))
} else {
pointable = nil
}
comments = try values.decodeIfPresent([String].self, forKey: .comments)
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(name, forKey: .name)
try container.encode(description, forKey: .description)
try container.encode(pointableType, forKey: .pointableType)
try container.encode(pointableId, forKey: .pointableId)
try container.encode(workingTime, forKey: .workingTime)
if let pointable = pointable {
switch pointable {
case .conferenceInterestPoint(let conferenceInterestPoint):
if let conferenceInterestPoint = conferenceInterestPoint {
try container.encode(conferenceInterestPoint, forKey: .pointable)
}
case .restaurantInterestPoint(let restaurantInterestPoint):
if let restaurantInterestPoint = restaurantInterestPoint {
try container.encode(restaurantInterestPoint, forKey: .pointable)
}
}
}
try container.encode(comments, forKey: .comments)
}
}
要解决多态对象的问题,请使用枚举:
enum Pointable {
case conferenceInterestPoint(ConferenceInterestPoint?)
case restaurantInterestPoint(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)
}
}
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)
}
}
final class InterestPoint: BaseInterestPoint {
let name: String?
let description: String?
let pointableType: String?
let pointableId: Int?
let workingTime: [Int]?
let pointable: Pointable?
let comments: [String]?
private enum CodingKeys: String, CodingKey {
case name
case description
case pointableType = "pointable_type"
case pointableId = "pointable_id"
case workingTime = "working_time"
case pointable
case comments
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
description = try values.decodeIfPresent(String.self, forKey: .description)
pointableType = try values.decodeIfPresent(String.self, forKey: .pointableType)
pointableId = try values.decodeIfPresent(Int.self, forKey: .pointableId)
workingTime = try values.decodeIfPresent([Int].self, forKey: .workingTime)
if pointableType == "ConferenceInterestPoint" {
pointable = .conferenceInterestPoint(try values.decodeIfPresent(ConferenceInterestPoint.self, forKey: .pointable))
} else if pointableType == "RestaurantInterestPoint" {
pointable = .restaurantInterestPoint(try values.decodeIfPresent(RestaurantInterestPoint.self, forKey: .pointable))
} else {
pointable = nil
}
comments = try values.decodeIfPresent([String].self, forKey: .comments)
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(name, forKey: .name)
try container.encode(description, forKey: .description)
try container.encode(pointableType, forKey: .pointableType)
try container.encode(pointableId, forKey: .pointableId)
try container.encode(workingTime, forKey: .workingTime)
if let pointable = pointable {
switch pointable {
case .conferenceInterestPoint(let conferenceInterestPoint):
if let conferenceInterestPoint = conferenceInterestPoint {
try container.encode(conferenceInterestPoint, forKey: .pointable)
}
case .restaurantInterestPoint(let restaurantInterestPoint):
if let restaurantInterestPoint = restaurantInterestPoint {
try container.encode(restaurantInterestPoint, forKey: .pointable)
}
}
}
try container.encode(comments, forKey: .comments)
}
}
本文中的所有代码都是在Xcode 10.2.1中测试的。也许您有以下类描述JSON的根:
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
和restaurantinterespoint
的基类:
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)
}
}
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)
}
}
final class InterestPoint: BaseInterestPoint {
let name: String?
let description: String?
let pointableType: String?
let pointableId: Int?
let workingTime: [Int]?
let pointable: Pointable?
let comments: [String]?
private enum CodingKeys: String, CodingKey {
case name
case description
case pointableType = "pointable_type"
case pointableId = "pointable_id"
case workingTime = "working_time"
case pointable
case comments
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
description = try values.decodeIfPresent(String.self, forKey: .description)
pointableType = try values.decodeIfPresent(String.self, forKey: .pointableType)
pointableId = try values.decodeIfPresent(Int.self, forKey: .pointableId)
workingTime = try values.decodeIfPresent([Int].self, forKey: .workingTime)
if pointableType == "ConferenceInterestPoint" {
pointable = .conferenceInterestPoint(try values.decodeIfPresent(ConferenceInterestPoint.self, forKey: .pointable))
} else if pointableType == "RestaurantInterestPoint" {
pointable = .restaurantInterestPoint(try values.decodeIfPresent(RestaurantInterestPoint.self, forKey: .pointable))
} else {
pointable = nil
}
comments = try values.decodeIfPresent([String].self, forKey: .comments)
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(name, forKey: .name)
try container.encode(description, forKey: .description)
try container.encode(pointableType, forKey: .pointableType)
try container.encode(pointableId, forKey: .pointableId)
try container.encode(workingTime, forKey: .workingTime)
if let pointable = pointable {
switch pointable {
case .conferenceInterestPoint(let conferenceInterestPoint):
if let conferenceInterestPoint = conferenceInterestPoint {
try container.encode(conferenceInterestPoint, forKey: .pointable)
}
case .restaurantInterestPoint(let restaurantInterestPoint):
if let restaurantInterestPoint = restaurantInterestPoint {
try container.encode(restaurantInterestPoint, forKey: .pointable)
}
}
}
try container.encode(comments, forKey: .comments)
}
}
会议兴趣点
和餐厅兴趣点
:
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)
}
}
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)
}
}
final class InterestPoint: BaseInterestPoint {
let name: String?
let description: String?
let pointableType: String?
let pointableId: Int?
let workingTime: [Int]?
let pointable: Pointable?
let comments: [String]?
private enum CodingKeys: String, CodingKey {
case name
case description
case pointableType = "pointable_type"
case pointableId = "pointable_id"
case workingTime = "working_time"
case pointable
case comments
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
description = try values.decodeIfPresent(String.self, forKey: .description)
pointableType = try values.decodeIfPresent(String.self, forKey: .pointableType)
pointableId = try values.decodeIfPresent(Int.self, forKey: .pointableId)
workingTime = try values.decodeIfPresent([Int].self, forKey: .workingTime)
if pointableType == "ConferenceInterestPoint" {
pointable = .conferenceInterestPoint(try values.decodeIfPresent(ConferenceInterestPoint.self, forKey: .pointable))
} else if pointableType == "RestaurantInterestPoint" {
pointable = .restaurantInterestPoint(try values.decodeIfPresent(RestaurantInterestPoint.self, forKey: .pointable))
} else {
pointable = nil
}
comments = try values.decodeIfPresent([String].self, forKey: .comments)
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(name, forKey: .name)
try container.encode(description, forKey: .description)
try container.encode(pointableType, forKey: .pointableType)
try container.encode(pointableId, forKey: .pointableId)
try container.encode(workingTime, forKey: .workingTime)
if let pointable = pointable {
switch pointable {
case .conferenceInterestPoint(let conferenceInterestPoint):
if let conferenceInterestPoint = conferenceInterestPoint {
try container.encode(conferenceInterestPoint, forKey: .pointable)
}
case .restaurantInterestPoint(let restaurantInterestPoint):
if let restaurantInterestPoint = restaurantInterestPoint {
try container.encode(restaurantInterestPoint, forKey: .pointable)
}
}
}
try container.encode(comments, forKey: .comments)
}
}
要解决多态对象的问题,请使用枚举:
enum Pointable {
case conferenceInterestPoint(ConferenceInterestPoint?)
case restaurantInterestPoint(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)
}
}
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)
}
}
final class InterestPoint: BaseInterestPoint {
let name: String?
let description: String?
let pointableType: String?
let pointableId: Int?
let workingTime: [Int]?
let pointable: Pointable?
let comments: [String]?
private enum CodingKeys: String, CodingKey {
case name
case description
case pointableType = "pointable_type"
case pointableId = "pointable_id"
case workingTime = "working_time"
case pointable
case comments
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
description = try values.decodeIfPresent(String.self, forKey: .description)
pointableType = try values.decodeIfPresent(String.self, forKey: .pointableType)
pointableId = try values.decodeIfPresent(Int.self, forKey: .pointableId)
workingTime = try values.decodeIfPresent([Int].self, forKey: .workingTime)
if pointableType == "ConferenceInterestPoint" {
pointable = .conferenceInterestPoint(try values.decodeIfPresent(ConferenceInterestPoint.self, forKey: .pointable))
} else if pointableType == "RestaurantInterestPoint" {
pointable = .restaurantInterestPoint(try values.decodeIfPresent(RestaurantInterestPoint.self, forKey: .pointable))
} else {
pointable = nil
}
comments = try values.decodeIfPresent([String].self, forKey: .comments)
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(name, forKey: .name)
try container.encode(description, forKey: .description)
try container.encode(pointableType, forKey: .pointableType)
try container.encode(pointableId, forKey: .pointableId)
try container.encode(workingTime, forKey: .workingTime)
if let pointable = pointable {
switch pointable {
case .conferenceInterestPoint(let conferenceInterestPoint):
if let conferenceInterestPoint = conferenceInterestPoint {
try container.encode(conferenceInterestPoint, forKey: .pointable)
}
case .restaurantInterestPoint(let restaurantInterestPoint):
if let restaurantInterestPoint = restaurantInterestPoint {
try container.encode(restaurantInterestPoint, forKey: .pointable)
}
}
}
try container.encode(comments, forKey: .comments)
}
}
这篇文章中的所有代码都是在Xcode 10.2.1中测试的。在我的回答中,我添加了一些类,因为您的问题中没有提供任何代码。我是否正确理解你的应用程序中有哪些类?在我的回答中,我添加了一些类,因为你没有在问题中提供任何代码。我是否正确理解你的应用程序中有哪些类?