I am unable to set the b
property in a child class. It is the parent class that inherits from Codable
, and that seems to be working well.
I feel like I am missing something really obvious, but I am having trouble seeing the wood for the trees.
Below is a playground example of my problem. b
remains 0, despite being set to 10
. It is the child class that gets passed in, but the parent property that can be set (very weird!).
class Primary : Codable {
var a: Int = 0
}
class Secondary : Primary {
var b: Int = 0
}
let c = Secondary.self
func testRef<T: Codable>(_ t: T.Type) {
let json = "{\"a\":5, \"b\" : 10}".data(using: .ascii)!
let testCodable = try? JSONDecoder().decode(t.self, from: json)
print("a >> \((testCodable as! Primary).a)")
print("b >> \((testCodable as! Secondary).b)")
}
testRef(c)
The output from this is:
a >> 5
b >> 0
Any tips or pointers would be gratefully received.
The magic of Codable
relies on simplicity (using structs which don't support inheritance).
The more custom, the more code
You have to write a custom initializer in the subclass to consider inheritance (thanks to Hamish for the note that CodingKeys and initializer are synthesized in the base class), I omitted the Encodable
part intentionally
class Primary : Decodable {
var a: Int
/*
private enum CodingKeys: String, CodingKey { case a }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
a = try container.decode(Int.self, forKey: .a)
}
*/
}
class Secondary : Primary {
var b: Int
private enum CodingKeys: String, CodingKey { case b }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
b = try container.decode(Int.self, forKey: .b)
try super.init(from: decoder)
}
}
func testRef<T: Decodable>() throws -> T {
let json = "{\"a\":5, \"b\" : 10}".data(using: .utf8)!
return try JSONDecoder().decode(T.self, from: json)
}
do {
let secondary : Secondary = try testRef()
print(secondary.a, secondary.b) // 5 10
} catch { print(error) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With