![](/img/trans.png)
[英]How to use Protocols and Delegates with UINavigationController
[英]How to use JSONDecoder with inheritance / protocols?
假设我有一个由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"
}
]
首先让我们将您的json转换为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
和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
有一个失败的初始化程序,它将尝试创建一个从ResponseElement
开始的Employee
。Employer
。
do {
let elements = try JSONDecoder().decode([ResponseElement].self, from: data)
let employees = elements.filter { $0.type == .employee }.flatMap(Employee.init)
let employers = elements.filter { $0.type == .employer }.flatMap(Employer.init)
print(employees.count)
print(employers.count)
} catch {
print("Something bad has happened 😱:\(error)")
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.