I was surprised recently to find that this:
protocol A: Encodable {}
class B: A {
var x = 3
}
class C: A {
var y = 4
}
let items: [A] = [B()]
let encoded = try JSONEncoder().encode(items)
Fails in Swift with:
Type 'any A' cannot conform to 'Encodable'
while this works:
let items: [B] = [B()]
let encoded = try JSONEncoder().encode(items)
Apparently the issue is that protocols do not conform to themselves. A workaround is provided in this answer.
I understand the reasoning and the workaround in the answers, but it is still quite inconvenient. Both of those answers are from ~2017; is there a cleaner way to solve this in swift 5?
Sample workaround :)
struct AnyEncodable: Encodable {
let item: any Encodable
func encode(to encoder: any Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(self.item)
}
}
let items: [A] = [B()]
let encoded = try JSONEncoder().encode(items.map { AnyEncodable(item: $0) })