I don't know how to handle this situation properly.
I have coded a value in a class.
When I decode, it should be a Bool, but it may be an Object (if created by an older version of the application, in Swift2 times).
So I used to do this :
var test : Bool
if decoder.containsValue(forKey: detailOptionsKey) { // key exists ; but was it created as Bool or as object (in Swift2)
test = decoder.decodeObject(forKey: detailOptionsKey) as? Bool ?? decoder.decodeBool(forKey: detailOptionsKey)
} else {
test = false
}
But In some cases I get the following crash message :
[General] *** -[NSKeyedUnarchiver decodeBoolForKey:]: value for key (detailOptionsKey) is not a boolean
My problem is that in :
test = decoder.decodeObject(forKey: detailOptionsKey) as? Bool ?? decoder.decodeBool(forKey: detailOptionsKey)
I have no way to test if decodeBool can be called ; but I need to call if value was encoded as a Bool (not an object)
I do not see how to test to avoid a crash.
I wonder if I could use decodeDecodable which can fail (that's what I need)
func decodeDecodable<T>(_ type: T.Type, forKey key: String) -> T? where T : Decodable
I tried
let test = (decoder as! NSKeyedUnarchiver).decodeDecodable(Bool.self, forKey: detailOptionsKey) ?? false
self.detailOptions = decoder.decodeObject(forKey: detailOptionsKey) as? Bool ?? test
which seems to work, but a bit convoluted.
Why do I need Bool.self ? and not just Bool
In anycases, as decodeBool (or decodeInteger, …) may crash, I would need to make my code more robust.
How can we know the type of the key, to use the appropriate decoder ?