First of all lets transform your json in a Data value
let data = """
[
{
"id": 1,
"type": "employee",
"employee_name": "xy"
},
{
"id": 2,
"type": "employer",
"employer_name": "xz"
}
]
""".data(using: .utf8)!
Important: Replace the "!" with a safer unwrapping method
Model
Now we need a model value to mach the element in your 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
}
}
As you can see employeeName and employerName are optionals, so this struct will be able to hold every element of your JSON (Employers and Employee).
Person and its subclasses
Assuming you have a class Person like this
class Person {
let id: Int
let name:String
init(id:Int, name:String) {
self.id = id
self.name = name
}
}
You'll need to create the Employee and Empolyer subclasses like these
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)
}
}
Please note that an Employee has a failable initializer that will try to create an Employee starting ResponseElement. Same for Employer.
Lets decode!
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)")
}