假设我在JSON中将employees
和employers
的单个数组混合在一起。两者都继承自Person
。在JSONDecoder中处理它的正确方法是什么?因为我们无法将其强制转换为子类,所以我们无法工作:
let decoder = JSONDecoder()
let persons = try! decoder.decode([Person].self, for: jsonData)
另一点:我们可以在这里使用协议而不是超类吗?
这就是我的示例JSON的样子:
[
{
"id": 1,
"type": "employee",
"employee_name": "xy"
},
{
"id": 2,
"type": "employer",
"employer_name": "xz"
}
]
答案 0 :(得分:0)
首先让我们在Data
值
let data = """
[
{
"id": 1,
"type": "employee",
"employee_name": "xy"
},
{
"id": 2,
"type": "employer",
"employer_name": "xz"
}
]
""".data(using: .utf8)!
重要提示:替换“!”使用更安全的展开方法
现在我们需要一个模型值来加工JSON中的元素
struct ResponseElement:Codable {
let id: Int
let type: Type
let employeeName: String?
let employerName: String?
enum CodingKeys: String, CodingKey {
case id, type, employeeName = "employee_name", employerName = "employer_name"
}
enum `Type`:String, Codable {
case employee, employer
}
}
正如您所看到的,
employeeName
和employerName
是选项,因此此结构将能够保存JSON的每个元素(Employers
和{{ 1}})。
假设你有一个类Employee
这样的
Person
您需要像这些
一样创建class Person {
let id: Int
let name:String
init(id:Int, name:String) {
self.id = id
self.name = name
}
}
和Employee
子类
Empolyer
请注意,
class Employee:Person { init?(responseElement:ResponseElement) { guard let name = responseElement.employeeName, responseElement.type == .employee else { return nil } super.init(id: responseElement.id, name: name) } } class Employer:Person { init?(responseElement:ResponseElement) { guard let name = responseElement.employerName, responseElement.type == .employer else { return nil } super.init(id: responseElement.id, name: name) } }
有一个可用的初始值设定项,会尝试创建Employee
起始Employee
。与ResponseElement
相同。
Employer
答案 1 :(得分:0)
我刚刚找到了一个很好的solution来解决这个问题。