近來項目需求冷守,需要用到了Rxswift和Moya,但是網(wǎng)上很多例子Moya都是基于Mapper封裝惊科,而Mapper的創(chuàng)建的代碼實在有點多拍摇,而且Swift4.0新特性之一就是官方自己出的JSON解析-Codable,那么我們就用起來吧馆截。
由于篇幅問題充活,Codable具體使用不在這里贅述
核心代碼
主要是封裝Moya的provider
/// 默認rx請求
///
/// - Parameters:
/// - api: api
/// - type: 解析類型
/// - Returns: 返回數(shù)據(jù)或錯誤
public static func rxRequest<T:Codable>(_ api :MultiTarget, type:T.Type) -> Single<T>{
let decoder = CleanJSONDecoder()
return self.provider.rx.request(api)
.asObservable()
.take(1)
.filterSuccess()
.map(type, using: decoder)
.observeOn(MainScheduler.instance)
.asSingle()
}
- 其中take(1)是保證該信號只執(zhí)行一次,避免了多次請求的問題
- moya也對codable做了分裝蜡娶,需要調用其對應方法就可以
- filterSuccess,在這個方法中主要對錯誤進行統(tǒng)一處理混卵,每個公司可能都每個公司自己的數(shù)據(jù)定義,這里也只是作為參考
public func filterSuccess() -> Observable<E> {
return flatMap { (response) -> Observable<E> in
let json = try JSON(response.mapJSON())
//這里的情況是窖张,只有code為0的時候幕随,數(shù)據(jù)data才有東西
if json.dictionaryValue["code"]?.intValue == 0{
//code為0,表示成功
return Observable.just(response)
}
//拋出錯誤
if let errormodel = try? JSONDecoder().decode(ErrorResponse.self, from: json.rawData()){
return Observable.error(HTTPServiceError.logic(err: errormodel))
}
return Observable.error(MoyaError.jsonMapping(response))
}
}
具體調用
//獲取語言
let api = MultiTarget(TestAPI.language)
//返回的是信息流 Single的
JFHTTPService.rxRequest(api, type: Languages.self).subscribe(onSuccess: { (languages) in
print(languages)
}) { (error) in
}.disposed(by: rx.disposeBag)
//獲取頻道 channel
let doubanList = MultiTarget(DouBanAPI.channels)
JFHTTPService.rxRequestData(doubanList, with: "channels", type: [Channel].self).subscribe(onSuccess: { [weak self](list) in
guard let self = self else{ return }
self.dataSource = list
self.table.reloadData()
print(list)
}) { (error) in
}.disposed(by: rx.disposeBag)
- 其中api使用MultiTarget宿接,這樣可以項目內使用多個target達到組件化赘淮,不用所有的請求都在一個文件,GitHub demo中有具體使用
- 返回的是Single的流數(shù)據(jù)睦霎,可以對應該信號梢卸,再做別的操作,例如重試(retry)碎赢、合并(flatMap)低剔、Map處理等等
- 傳入的可以是該model的類型(model.self)或者是數(shù)組的類型([model].self)
舉個例子
GitHub例子
Demo