Dear all,
I have run into the following issue: I am trying to decode a json file that consists of different sub-classes with different information degrees. Let me explain with a simplified example:
Class
class Vehicle: Codable {
var currentlyDrives: Bool
var speed: Double
init(drives: Bool, speed: Double) {
self.currentlyDrives = drives
self.speed = speed
}
}
class Car: Vehicle {
var numberOfPassengers: Int
init(drives: Bool, speed: Double, numPax: Int) {
self.numberOfPassengers = numPax
super.init(drives: drives, speed: speed)
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
numberOfPassengers = try container.decode(Int.self, forKey: .numberOfPassengers)
try super.init(from: decoder)
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(numberOfPassengers, forKey: .numberOfPassengers)
try super.encode(to: encoder)
}
enum CodingKeys: String, CodingKey {
case numberOfPassengers
}
}
If I am creating instances of both "Vehicles" and "Cars" and putting everything in an array, I have no problem encoding to a proper JSON file (including all properties of Cars if we have a car and only properties of vehicles if we have a vehicle (see below)).
let car = Car(drives: true, speed: 123, numPax: 5)
let bike = Vehicle(drives: true, speed: 12)
var array = [Vehicle]()
array.append(car)
array.append(bike)
let encoded = try! JSONEncoder().encode(array)
print(String(data: encoded, encoding: .utf8)!)
The above prints a proper JSON as follows with car having the additional "numberOfPassengers" property:
[{"currentlyDrives":true,"numberOfPassengers":5,"speed":123},{"currentlyDrives":true,"speed":12}]
When decoding I am able to read back all Vehicles without a problem. However what I would like to achieve is reading back a vehicle as a car if it is one (i.e. being able to read "numberOfPassengers".
Do you have any idea how this would be achievable?
Many thanks in advance and best regards,
Julian