swift5 - 如何从 Combine + Alamofire 错误响应中获取数据值?
问题描述
下面是我调用 api 的代码,当 api 调用出错时它返回 Swift.Error 。
AccountAPI.postAccount(withSignUpCommand: signUpCommand)
.sink(receiveCompletion: { [weak self] result in
guard let self = self else { return }
switch result {
case .finished:
self.logger.debug("signUp completed.")
case .failure(let error):
self.isAuthenticating = false
self.logger.error("signUp error : \(error)")
}
}, receiveValue: { [weak self] (statusCode, userId) in
guard let self = self else { return }
self.logger.debug("signUp status code : \(statusCode)")
guard (200...299).contains(statusCode) else {
return
}
self.logger.debug("UserId: \(userId)")
})
.store(in: &disposables)
我的出版商在这里
static func postAccount(
withSignUpCommand signUpCommand: SignUpCommand,
apiResponseQueue: DispatchQueue = CloudHospitalClientAPI.apiResponseQueue
) -> AnyPublisher<(Int, String), Error> {
let url = "\(CloudHospitalClientAPI.identityBasePath)/api/v1/accounts"
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: signUpCommand)
return Future<(Int, String), Error>.init { promise in
postAccountWithRequestBuilder(withURLString: url, withParameters: parameters, isBody: true).execute(apiResponseQueue) { result -> Void in
switch result {
case let .success(response):
promise(.success((response.statusCode, response.body!)))
case let .failure(error):
promise(.failure(error))
}
}
}
.eraseToAnyPublisher()
}
static func postAccountWithRequestBuilder(
withURLString URLString: String,
withParameters parameters: [String: Any]?,
isBody: Bool
) -> RequestBuilder<String> {
let url = URLComponents(string: URLString)
let requestBuilder: RequestBuilder<String>.Type = CloudHospitalClientAPI.requestBuilderFactory.getBuilder()
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: isBody)
}
以下格式的 api 错误响应,我想解析这个数据,但根本无法访问这个值。
尝试将返回类型更改为自定义错误响应,但没有运气。
请分享一些建议,我可以在其中插入解码错误响应代码并返回调用者函数。
提前致谢。
感谢布鲁诺,下面是我编辑的代码。
AccountAPI.postAccount(withSignUpCommand: signUpCommand)
.sink(receiveCompletion: { [weak self] result in
guard let self = self else { return }
switch result {
case .finished:
self.logger.debug("signUp completed.")
case .failure(let error):
self.isAuthenticating = false
self.logger.error("signUp error : \(error)")
if case let ErrorResponse.error(_, data, _) = error {
let decoder = JSONDecoder()
let identityErrors = try! decoder.decode([IdentityError].self, from: data!)
// TODO: Decode `data` here...
self.logger.debug("data: \(String(describing: identityErrors))")
self.errors = identityErrors
}
}
}, receiveValue: { [weak self] (statusCode, userId) in
guard let self = self else { return }
self.logger.debug("signUp status code : \(statusCode)")
guard (200...299).contains(statusCode) else {
return
}
self.logger.debug("UserId: \(userId)")
})
.store(in: &disposables)
解决方案
你能检查一下这是否解决了你的问题吗?
AccountAPI.postAccount(withSignUpCommand: signUpCommand)
.sink(receiveCompletion: { [weak self] result in
guard let self = self else { return }
switch result {
case .finished:
self.logger.debug("signUp completed.")
case .failure(let error):
self.isAuthenticating = false
self.logger.error("signUp error : \(error)")
if case let ErrorResponse.error(statusCode, data, error) = error {
// TODO: Decode `data` here...
}
}
}, receiveValue: { [weak self] (statusCode, userId) in
guard let self = self else { return }
self.logger.debug("signUp status code : \(statusCode)")
})
.store(in: &disposables)
推荐阅读
- php - 通过 html 表单从日期数组中获取日期
- lisp - 如何使用“采取”词作为 CLOS 泛型
- android - Oreo 上的联系地址簿共享一个 .vcf 文件而不是带有查找键的 URI
- python - 通过 multiindex 将 Series 分配给 DataFrame
- javascript - Three.js:渲染第一帧花费太多时间
- audio - VST 插件可以将传入的音频保存到外部 wav 文件(与 DAW 分开)吗?
- r - group_by 并使用 dplyr 对列求和,但未给出预期结果
- docker - 从官方 docker 镜像启动时,payara 完整应用服务器的管理控制台的默认用户名和密码是什么?
- discord.js - 如何发送随机图像?
- facebook - Facebook 需要刮两次才能得到正确的 OpenGraph 图像