I have a Swift class that may or may not be Codable
. When it is Codable
, I would like to be able to load it from file. Here is a bare bones example...
protocol P {
func load()
}
final class A<T>: P {
func load() {
if T.self is Codable.Type {
let decoded = try JSONDecoder().decode(Self.self, from: Data())
}
}
}
extension A: Codable where T: Codable {}
I get an error that T
is not Codable
and the JSONDecoder
requires it. It makes sense, because even though I do a run time check, the call to decode
does not constrain T
to be Codable
.
I've tried a bunch of variations, like adding extensions with a where
clause, but I'm yet to find the definitive answer.
Anyone know how to approach this?
import Cocoa
protocol P {
func load(from data: Data)
}
extension P {
func load(from data: Data) {
// print or something
Swift.print("P.load")
}
}
final class A<T>: P {
}
extension A: Codable where T: Codable {
func load(from data: Data) {
Swift.print("A.load where T Codable")
let decoded = try! JSONDecoder().decode(Self.self, from: data)
}
}
extension A {
func load(from data: Data) {
Swift.print("A.load")
}
}
let four = 4
let encoded = try JSONEncoder().encode(four)
A<Int>().load(from: encoded)
This worked for me in a playground. If overloading isn't working for you, then there is something like throws
interacting with the compiler/runtime's choice of implementation.