Swift-自己封裝一個網(wǎng)絡請求,基于Rxswift、Moya、Codable

近來項目需求,需要用到了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()
    }
  1. 其中take(1)是保證該信號只執(zhí)行一次,避免了多次請求的問題
  2. moya也對codable做了分裝,需要調用其對應方法就可以
  3. 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)
  1. 其中api使用MultiTarget,這樣可以項目內使用多個target達到組件化,不用所有的請求都在一個文件,GitHub demo中有具體使用
  2. 返回的是Single的流數(shù)據(jù),可以對應該信號,再做別的操作,例如重試(retry)、合并(flatMap)、Map處理等等
  3. 傳入的可以是該model的類型(model.self)或者是數(shù)組的類型([model].self)

舉個例子

GitHub例子
Demo

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容