Exception from deep within when decoding a derived class inside an object
jkufver opened this issue · comments
Hi thanks for the updated version 1.0.9.
I just stumbled upon another issue with Juice.
I have a class B
which inherits from a super class A
:
class A: Juice.Decodable {
var a: String?
required init(fromJson json: Juice.JSONDictionary) throws {
a = try? json.decode(["a"])
}
}
class B: A {
var b: String?
required init(fromJson json: Juice.JSONDictionary) throws {
b = try? json.decode(["b"])
try super.init(fromJson: json)
}
}
When I decode B (in my case an array of B's (not shown in this reduced example)) I get an exception from deep inside of Juice.
Example code:
// Decoding simple object B -> Works
do {
let string = "{\"a\": \"Apple 0\", \"b\": \"Brother 0\"}"
let dict = try toStrictlyTypedJSON(toLooselyTypedJSON(string)) as! JSONDictionary
let o = try B(fromJson: dict)
print(o.a, o.b)
} catch {
print(error.localizedDescription)
}
// B as a part of an object -> Fails
do {
let string = "{\"object\": {\"a\": \"Apple 1\", \"b\": \"Brother 1\"}}"
let dict = try toStrictlyTypedJSON(toLooselyTypedJSON(string)) as! JSONDictionary
// This works
let oa: A = try dict.decode("object")
print(oa.a)
// This fails with exception "Could not cast value of type 'A' to 'B'"
let ob: B = try dict.decode("object")
print(ob.a, ob.b)
} catch {
print(error.localizedDescription)
}
My knowledge of generics is a bit to shallow to find the reason.
All the best
Hmm, that's interesting. Will require a closer look, but in the mean time, this workaround seems to work for me:
let ob: B = try dict.decode("object") { (dict: JSONDictionary) in
return try B(fromJson: dict)
}
Hi thanks for the feedback.
I solved my urgent need by not using a derived class.
Your suggestion would not solve my need since in my case B is a part of a another object.
class C: Juice.Decodable {
let bs: [B]
…
}
and to decode C
and all B
s the dict.decode(…)
method must work. At least I think so...
Today I understood what you wrote two days ago. Sorry about that...
With the transform functionality I can now parse an array of B
s:
let arr: [B] = try dict.decode("arr") { (arr: JSONArray) in
try arr.map {
guard let dict = $0 as? JSONDictionary else {
throw MismatchError.typeMismatch(expected: JSONDictionary.self, got: $0)
}
return try B(fromJson: dict)
}
}