Я использую дженерики и кодирую с URLSession
.
Когда я получаю ответ от API, я проверяю, что статус находится в диапазоне от 200 до 299, и декодирую данные следующим образом
guard let data = data, let value = try? JSONDecoder().decode(T.self, from: data) else {
return completion(.error("Could not decode JSON response"))
}
completion(.success(value))
Затем это передается обработчику завершения, и все в порядке.
У меня есть новая конечная точка, я тоже должен выполнить POST, но эта конечная точка возвращает 204 без тела содержимого.
Таким образом, я не могу расшифровать ответ, просто как я не могу передать тип?
Мой обработчик завершения ожидает
enum Either<T> {
case success(T)
case error(String?)
}
и включил мой ответ statusCode вот так
case 204:
let value = String(stringLiteral: "no content")
return completion(.success(value))
выдает ошибку
Элемент «success» в «Either‹ > »дает результат типа« Either », но контекст ожидает« Either ‹>»
Мой APIClient
protocol APIClientProtocol: class {
var task: URLSessionDataTask { get set }
var session: SessionProtocol { get }
func call<T: Codable>(with request: URLRequest, completion: @escaping (Either<T>) -> Void) -> Void
func requestRefreshToken<T: Codable>(forRequest failedRequest: URLRequest, completion: @escaping (Either<T>) -> Void) -> Void
}
extension APIClientProtocol {
func call<T: Codable>(with request: URLRequest, completion: @escaping (Either<T>) -> Void) -> Void {
task = session.dataTask(with: request, completionHandler: { [weak self] data, response, error in
guard error == nil else {
return completion(.error("An unknown error occured with the remote service"))
}
guard let response = response as? HTTPURLResponse else {
return completion(.error("Invalid HTTPURLResponse recieved"))
}
switch response.statusCode {
case 100...299:
guard let data = data else { return completion(.error("No data in response")) }
guard let value = try? JSONDecoder().decode(T.self, from: data) else { return completion(.error("Could not decode the JSON response")) }
completion(.success(value))
case 300...399: return completion(.error(HTTPResponseStatus.redirection.rawValue))
case 400: return completion(.error(HTTPResponseStatus.clientError.rawValue))
case 401: self?.requestRefreshToken(forRequest: request, completion: completion)
case 402...499: return completion(.error(HTTPResponseStatus.clientError.rawValue))
case 500...599: return completion(.error(HTTPResponseStatus.serverError.rawValue))
default:
return completion(.error("Request failed with a status code of \(response.statusCode)"))
}
})
task.resume()
}
}
.error(value)
? Или добавьте третий случай. Кстати, а почему строка в случае ошибки необязательна? Значениеnil
не имеет смысла. Я бы дажеcatch
ошибку при декодировании JSON и вернул бы (case error(DecodingError)
) - person vadian   schedule 06.01.2019