I have the following Swift code
func doStuff<T: Encodable>(payload: [String: T]) {
let jsonData = try! JSONEncoder().encode(payload)
// Write to file
}
var things: [String: Encodable] = [
"Hello": "World!",
"answer": 42,
]
doStuff(payload: things)
results in the error
Value of protocol type 'Encodable' cannot conform to 'Encodable'; only struct/enum/class types can conform to protocols
How to fix? I guess I need to change the type of things, but I don't know what to.
Additional info:
If I change doStuff to not be generic, I simply get the same problem in that function
func doStuff(payload: [String: Encodable]) {
let jsonData = try! JSONEncoder().encode(payload) // Problem is now here
// Write to file
}
Codable is the combined protocol of Swift's Decodable and Encodable protocols. Together they provide standard methods of decoding data for custom types and encoding data to be saved or transferred.
Codable is a type alias for the Encodable and Decodable protocols. When you use Codable as a type or a generic constraint, it matches any type that conforms to both protocols.
Encodable cannot be used as an annotated type. It can be only used as a generic constraint. And JSONEncoder can encode only concrete types.
The function
func doStuff<T: Encodable>(payload: [String: T]) {
is correct but you cannot call the function with [String: Encodable] because a protocol cannot conform to itself. That's exactly what the error message says.
The main problem is that the real type of things is [String:Any] and Any cannot be encoded.
You have to serialize things with JSONSerialization or create a helper struct.
You can use the where keyword combined with Value type, like this:
func doStuff<Value>(payload: Value) where Value : Encodable {
...
}
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