Swift 4 - Cannot invoke 'encode' with an argument list of type '(Codable)'

702 Views Asked by At

I have built a set of API functions which encode an object (using a Struct which conforms to Codable), then Posts the resulting JSON Data object to a server, then decodes the JSON response. All works fine - especially happy with the new method for JSON parsing in Swift 4.2. However, now I want to refactor the code so that I can reuse the code for various method calls - when I do I get a really annoying error.

func encodeRequestJSON(apiRequestObject: Codable) -> Data {
    do {
        let encoder = JSONEncoder()
        let jsonData = try encoder.encode(apiRequestObject)
        let jsonString = String(data: jsonData, encoding: .utf8)
        print(jsonString)
    } catch {
        print("Unexpected error")
        }
    return jsonData!
}

This is the error message:

Cannot invoke 'encode' with an argument list of type '(Codable)'

I have tried changing the type from Codable, to Encodable but get the same error, except with type (Encodable) in the message. Any advice? My fall-back is to encode the data in the current ViewController, then call the HTTPPost function and then decode back in the VC. But that's really clunky.

1

There are 1 best solutions below

0
On BEST ANSWER

You need a concrete type to be passed into JSONEncoder.encode, so you need to make your function generic with a type constraint on Encodable (Codable is not needed, its too restrictive).

func encodeRequestJSON<T:Encodable>(apiRequestObject: T) throws -> Data {
    return try JSONEncoder().encode(apiRequestObject)
}