I have a function to talk to my REST server as follows
func send<T: Decodable>(_ request: HTTPSClient.Request) async throws -> T {
do {
let (data, status): (Data, HTTPSClient.StatusCode) = try await request.send()
if status.responseType != .success { // success means 2xx
throw try JSONDecoder().decode(CustomError.self, from: data)
}
return try JSONDecoder().decode(T.self, from: data)
} catch {
// some error handling here
}
}
And is called as follows
public struct API1Response: Codable {
// some fields
}
...
let response: API1Response = try await self.send(httpsRequest)
Now I have a special use case where the response needs to be JSON decoded into different structs based on the HTTP response status code (2xx).
For example, if the response code is 200 OK, it needs to be decoded into struct APIOKResponse
. If the response code is 202 Accepted, it needs to be decoded into struct APIAcceptedResponse
and so on.
I want to write a similar function as above which can support multiple response types
I have written the below function, it does not throw any compilation errors
func send<T: Decodable>(_ request: HTTPSClient.Request, _ types: [HTTPSClient.StatusCode: T.Type]) async throws -> T {
do {
let (data, status): (Data, HTTPSClient.StatusCode) = try await request.send()
if status.responseType != .success { // success means 2xx
throw try JSONDecoder().decode(CustomError.self, from: data)
}
guard let t = types[status] else {
throw ClientError.unknownResponse
}
return try JSONDecoder().decode(t.self, from: data)
} catch {
// some error handling here
}
}
I don't understand how to call this though. Tried below
struct APIAcceptedResponse: Codable {
// some fields
}
struct APIOKResponse: Codable {
// some fields
}
...
let response = try await self.send(httpsRequest, [.accepted: APIAcceptedResponse, .ok: APIOKResponse])
// and
let response = try await self.send(httpsRequest, [.accepted: APIAcceptedResponse.self, .ok: APIOKResponse.self])
But in both cases it shows error
Cannot convert value of type 'APIAcceptedResponse.Type' to expected dictionary value type 'APIOKResponse.Type'
- Is there something I am doing wrong in the
send
function itself? - If not, how to call it?
- Is this is something can be achieved even?