Swift 4 - Cannot invoke 'encode' with an a

2020-04-15 21:05发布

问题:

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:

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)
}