在我的应用程序中,我使用Moya和Alamofire(以及 Moya/RxSwift 和Moya-ObjectMapper)库来处理所有网络请求和响应。
我想在一个处理程序中处理所有类型的请求的响应,但也唯一地处理每个请求。
例如,对于任何请求,我都可以获得响应“无效版本”,如果出现此错误,我想避免检查每个响应。
有没有一种优雅的方式来处理这个用例Moya
?
显然这很简单,您只需创建自己的插件。并将其添加到您的 Provider 实例中(您可以在 init 函数中添加它)
例如:
struct NetworkErrorsPlugin: PluginType {
/// Called immediately before a request is sent over the network (or stubbed).
func willSendRequest(request: RequestType, target: TargetType) { }
/// Called after a response has been received, but before the MoyaProvider has invoked its completion handler.
func didReceiveResponse(result: Result<Moya.Response, Moya.Error>, target: TargetType) {
let responseJSON: AnyObject
if let response = result.value {
do {
responseJSON = try response.mapJSON()
if let response = Mapper<GeneralServerResponse>().map(responseJSON) {
switch response.status {
case .Failure(let cause):
if cause == "Not valid Version" {
print("Version Error")
}
default:
break
}
}
} catch {
print("Falure to prase json response")
}
} else {
print("Network Error = \(result.error)")
}
}
}
我建议使用通用参数化方法。
class DefaultNetworkPerformer {
private var provider: RxMoyaProvider<GitHubApi> = RxMoyaProvider<GitHubApi>()
func performRequest<T:Mappable>(_ request: GitHubApi) -> Observable<T> {
return provider.request(request).mapObject(T.self)
}
}
DefaultNetworkPerformer
将处理来自您 Moya 的所有请求TargetType
。就我而言,它是GitHubApi
。此实现的示例用法是:
var networkPerformer = DefaultNetworkPerformer()
let observable: Observable<User> = networkPerformer.performRequest(GitHubApi.user(username: "testUser"))
在这里,您“通知”网络执行者响应将包含User
对象。
observable.subscribe {
event in
switch event {
case .next(let user):
//if mapping will succeed here you'll get an Mapped Object. In my case it was User that conforms to Mappable protocol
break
case .error(let error):
//here you'll get MoyaError if something went wrong
break
case .completed:
break
}
}