【发布时间】:2020-11-30 09:59:15
【问题描述】:
我正在调用的 API 可以返回包含错误消息的 JSON。
如果我希望在成功请求时返回另一个 Decodable 对象,我如何告诉 Combine 尝试解码此自定义错误?
我的代码目前如下所示:
private var cancellable: AnyCancellable?
internal func perform<T>(request: URLRequest, completion: @escaping (Result<T, Error>) -> Void) where T: Decodable {
cancellable = session.dataTaskPublisher(for: request)
.tryMap { output in
guard let response = output.response as? HTTPURLResponse, response.statusCode == 200 else {
throw HTTPError.statusCode
}
return output.data
}
.decode(type: T.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
.sink(receiveCompletion: { _completion in
guard case .failure(let error) = _completion else {
return
}
completion(.failure(error))
}, receiveValue: { value in
completion(.success(value))
})
}
有了URLSession,我会做这样的事情:
URLSession.shared.dataTask(with: request) { data, response, error in
// Check for any connection errors
if let error = error {
completion(.failure(error))
return
}
// Read data
guard let data = data, !data.isEmpty else {
completion(.failure(SPTError.noDataReceivedError))
return
}
// Check response's status code, if it's anything other than 200 (OK), try to decode SPTError from the data.
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
let sptError = (try? JSONDecoder().decode(SPTError.self, from: data)) ?? SPTError.badRequest
completion(.failure(sptError))
return
}
// Decode requested objects
do {
let object = try JSONDecoder().decode(T.self, from: data)
completion(.success(object))
} catch {
print(completion(.failure(error)))
}
}.resume()
SPTError只是一个包含代码和消息的结构体,它符合Codable
【问题讨论】:
-
你当前的代码有什么问题?
-
它只尝试解码
T对象,如果响应与200代码不同,它会引发一般错误,我想将数据解码为SPTError
标签: ios swift nsurlsession combine urlsession