将 Moya 响应错误转换为定义的类型
Posted
技术标签:
【中文标题】将 Moya 响应错误转换为定义的类型【英文标题】:Casting Moya Response error to defined type 【发布时间】:2019-08-30 10:19:52 【问题描述】:我正在使用 RxMoya 进行网络调用并扩展 PremitiveSequence 和 Response 以处理返回的错误。我声明了一个网络错误结构,我可以使用它来获取所有错误详细信息,并通过 BaseResponse 模型传递错误消息。这是我的 NetworkingError 结构
public struct NetworkingError: Error
let httpResponse: HTTPURLResponse?
let networkData: Data?
let baseError: Error
对于我的编码,我将原始序列扩展如下
公共扩展 PrimitiveSequence 其中 TraitType == SingleTrait,
ElementType == Response
func mapObject<T: Codable>(_ type: T.Type, path: String? = nil) -> Single<T>
return flatMap response -> Single<T> in
return Single.just(try response.mapObject(type, path: path))
func mapArray<T: Codable>(_ type: T.Type, path: String? = nil) -> Single<[T]>
return flatMap response -> Single<[T]> in
return Single.just(try response.mapArray(type, path: path))
func filterSuccess() -> Single<E>
return flatMap (response) -> Single<E> in
if 200 ... 299 ~= response.statusCode
return Single.just(response)
print("THIS ERROR JSON jsonObject2 xx mm \(response.data)")
do
let jsonObject2 = try JSONSerialization.jsonObject(with: response.getJsonData(), options: .allowFragments)
print("THIS ERROR JSON jsonObject2 xx \(jsonObject2)")
let jsonObject = try JSONSerialization.jsonObject(with: response.getJsonData(), options: .allowFragments) as? NetworkingError
print("THIS ERROR JSON xx \(jsonObject)")
return Single.error(jsonObject ?? NetworkingError.self as! Error)
如果我在这里运行此代码,应用程序会崩溃 return Single.error(jsonObject ?? NetworkingError.self as! Error)
在我的代码中,我传递的数据类似于
func postVerifyApp(challenge: Int, identifier: String) -> Observable<AuthResponse>
return provider.rx.request(.postVerifyApp(challenge: challenge, identifier: identifier))
.filterSuccess()
.mapObject(AuthResponse.self)
.asObservable()
.flatMap( authResponse -> Observable<AuthResponse> in
return self.sendTokenToServer(authResponse)
)
然后我正在像这样在我的演示者类中使用它
func postVerifyApp(challenge: Int, identifier: String)
view?.setProgress(enabled: true)
source.postVerifyApp(challenge: challenge, identifier: identifier)
.retry(.delayed(maxCount: 2, time: 2.5), shouldRetry: networkRetryPredicate)
.asSingle()
.subscribe(onSuccess: [weak self] response in
guard let presenter = self, let view = presenter.view else return
view.setProgress(enabled: false)
log(response, .json)
guard let data = response.data else
return
view.showVerifySuccess()
, onError: [weak self] error in
guard let presenter = self, let view = presenter.view else return
print("MESSAGE X \(error.localizedDescription)")
if let error = error as? NetworkingError
print("MESSAGE X httpResponse \(error.httpResponse)")
view.setProgress(enabled: false)
).disposed(by: disposeBag)
我希望能够传递此错误并提取错误消息并将其传递给控制台。
这是我的基本模型的样子
struct ResponseBase<T: Codable>: Codable
var error: Bool?
var message: String?
var data: T
var isSucessful: Bool
return error == false
【问题讨论】:
【参考方案1】:用于构造 Single.error 的表达式不能转换为 Error。首先,您尝试将 jsonObject(字典)转换为错误。在右侧,在 ifNull 表达式中,您尝试将元类型 (Networking.Type) 转换为错误。
要解决您的投射问题,您可以使用修改后的 NetworkingError。
public struct NetworkingError: Error
let httpResponse: HTTPURLResponse?
let networkData: Data?
let baseError: MoyaError
init(_ response:Response)
self.baseError = MoyaError.statusCode(response)
self.httpResponse = response.response
self.networkData = response.data
func getLocalizedDescription() -> String
return self.baseError.localizedDescription
有了这个,修改 filterSuccess 中的闭包来创建 NetworkingError 对象,将 Response 传递给它,就像这样:
func filterSuccess() -> Single<E>
return flatMap
(response) -> Single<E> in
if 200 ... 299 ~= response.statusCode
return Single.just(response)
else
let netError = NetworkingError(response)
return Single.error(netError)
我鼓励你看看 MoyaError 的定义
【讨论】:
以上是关于将 Moya 响应错误转换为定义的类型的主要内容,如果未能解决你的问题,请参考以下文章
Dojo.js AMD 加载程序 - 类型错误:无法将未定义转换为对象