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