When conforming to Codable
protocol, I cannot easily skip optional property of non-Codable class
In Ride
struct we want to skip encoding and decoding of driver
property, and just leave it nil
when decoding:
struct Ride: Codable {
public var number: String
public var passenger: Passenger? // Codable conforming
public var driver: Driver? // NSObject subclass, doesn't conform to Codable
enum CodingKeys: String, CodingKey {
case number
case passenger
}
}
In this case I get a compile error
Type 'Driver' does not conform to protocol 'Decodable'
So far the only solution I came with, is to encode and decode manually by providing following methods:
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
number = try? values.decode(String.self, forKey: .number)
passenger = try? values.decode(Passenger.self, forKey: .passenger)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(number, forKey: .number)
try container.encode(passenger, forKey: .passenger)
}
Is there another way to skip an optional property? This would be much easier with bigger models.
Try providing a default value for driver
. For instance, this compiled without errors on Xcode 9.0:
struct Ride: Codable {
public var number: String
public var passenger: Passenger?
public var driver: Driver? = nil
private enum CodingKeys: String, CodingKey {
case number
case passenger
}
}
struct Passenger: Codable { /* ... */ }
class Driver: NSObject { /* ... */ }
Quick test:
let rideJSON =
"""
{
"number": "123"
}
""".data(using: .utf8)!
let ride = try! JSONDecoder().decode(Ride.self, from: rideJSON)
print(ride) /* Ride(number: "123", passenger: nil, driver: nil) */
By the way, I used a private CodingKeys
because that is what the compiler does by default as well ;)