使用具有API响应的泛型/可编码204没有内容

时间:2019-01-06 10:46:46

标签: swift nsurlsession codable urlsession jsondecoder

我使用的是泛型,并且可以与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)) 

然后将其传递给完成处理程序,一切正常。

我有一个新端点,我也必须过帐,但是,此端点返回没有内容主体的204。

这样,我无法解码响应,就像无法传递类型一样?

我的完成处理程序期望

enum Either<T> {
    case success(T)
    case error(String?)
}

并像这样打开我的响应statusCode

   case 204:
        let value = String(stringLiteral: "no content")
        return completion(.success(value))

产生错误

  

'Either << em >>'中的成员'success'产生类型为'Either'的结果,   但是上下文期望“ Either << / em >>”

我的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()
    }
}

1 个答案:

答案 0 :(得分:1)

将您的Either枚举成功类型设置为可选

enum Either<T> {
    case success(T?)
    case error(String)
}

204响应状态创建案例,并传递nil

    case 204:
        completion(.success(nil))

然后您可以使用typealias并创建

之类的通用名称
typealias NoContentResponse = Either<Bool>

然后您应该可以打开NoContentResponse