亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

淺談RxSwift 網絡請求

2019-10-21 18:40:18
字體:
來源:轉載
供稿:網友

一、說明

入坑RxSwift 有段時間了,之前在項目中只是小范圍的使用RxSwift,為了更好的使用響應式編程,決定在項目中更廣范圍的使用RxSwift,然后研究了一下RxSwift的網絡請求,現在有關網絡請求的案例大多是基于RXSwift(4.0.0)或者更早的庫來寫的,本篇文章是基于目前最新的版本(4.2.0)版本來寫的,由于RxSwift 版本的更新,里面的使用語法,發生了變化,在整理的過程中遇到了一些問題,為了讓后來學習的小伙伴,節約時間,決定記錄下來

二、網絡請求

1.使用RxSwift相關庫的版本

  • ObjectMapper (3.2.0)
  • HandyJSON (4.1.1)
  • Moya (11.0.2)
  • RxCocoa (4.2.0)
  • RxSwift (4.2.0)

2.在Swift語言中,我們使用Alamofire 作為網絡庫,moya 是對Alamofire 更抽象一層的封裝,RxSwift把Moya封裝后作為網絡請求的接口,我們在使用的時候只需要實現 TargetType 協議就好,用一個例子來看下怎么使用:

import Foundationimport Moyaenum APIService{  case mainClassList}extension APIService:TargetType{  var baseURL: URL {    return URL(string:"http://cmsadmin.fotoable.net")!  }    var path: String {    switch self {    case .mainClassList:       return "/sandboxColor/category"    }  }    var method: Moya.Method {    switch self {    case .mainClassList:       return .get    }  }    var parameters: [String : Any]? {        switch self {    case .mainClassList:      return nil    }  }    var parameterEncoding: ParameterEncoding {        return URLEncoding.default  }    var sampleData: Data {    return "{}".data(using: String.Encoding.utf8)!  }    var task: Task {    return .requestPlain  }    var headers: [String : String]? {    return nil  }}

首先,我們定義了一個 枚舉 APIService ,作用主要是在內部定義網絡請求的接口,然后,就是對協議 TargetType進行擴展,我們一一解讀下里面的參數

  • baseURL:網絡請求的基本URL
  • path:用于匹配具體網絡請求接口
  • method:網絡請求方式,常用就是 get/post 兩種
  • parameters:接口請求時要帶的參數
  • parameterEncoding:參數編碼方式(這里使用URL的默認方式)
  • sampleData:這里用于單元測試
  • task:執行網絡請求的任務
  • validationType:是否執行Alamofire驗證,默認值為false
  • headers:網絡請求時需要的header,如果和后臺沒有特殊的驗證處理,默認傳nil 就可以
  • APIService 作為網絡請求的統一接口,里面封裝了網絡請求所需的一些基本數據

3.在進行網絡請求之前,需要做一些準備工作,把網絡請求回的數據通過JSON 轉化成 Model , 這里我們使用了兩種方式進行轉換(根據項目的情況,靈活選擇使用),一種通過 ObjectMapper庫進行轉換,一種是通過 HandyJSON 庫 進行轉換 ,分別通過對 Response 類 擴展 ,以下是對這兩種方式的封裝

其一:使用 ObjectMapper庫 把JSON 轉換成 Model

import Foundationimport RxSwiftimport Moyaimport ObjectMapper// MARK: - Json -> Modelextension Response {    func mapObjectModel<T: BaseMappable>(_ type: T.Type, context: MapContext? = nil) throws -> T {    guard let object = Mapper<T>(context: context).map(JSONObject: try mapJSON()) else {      throw MoyaError.jsonMapping(self)    }    return object  }    func mapObjectArray<T: BaseMappable>(_ type: T.Type, context: MapContext? = nil) throws -> [T] {    guard let array = try mapJSON() as? [[String : Any]] else {      throw MoyaError.jsonMapping(self)    }    return Mapper<T>(context: context).mapArray(JSONArray: array)  }}// MARK: - Json -> Observable<Model>extension ObservableType where E == Response {  // 將Json解析為Observable<Model>  public func mapObjectModel<T: BaseMappable>(_ type: T.Type) -> Observable<T> {    return flatMap { response -> Observable<T> in      return Observable.just(try response.mapObjectModel(T.self))    }  }  // 將Json解析為Observable<[Model]>  public func mapObjectArray<T: BaseMappable>(_ type: T.Type) -> Observable<[T]> {    return flatMap { response -> Observable<[T]> in      return Observable.just(try response.mapObjectArray(T.self))    }  }}

其二 : 使用 HandyJSON 庫 把JSON 轉化成 Model

import Foundationimport RxSwiftimport Moyaimport HandyJSONextension ObservableType where E == Response {  public func mapHandyJsonModel<T: HandyJSON>(_ type: T.Type) -> Observable<T> {    return flatMap { response -> Observable<T> in      return Observable.just(response.mapHandyJsonModel(T.self))    }  }}extension Response {  func mapHandyJsonModel<T: HandyJSON>(_ type: T.Type) -> T {    let jsonString = String.init(data: data, encoding: .utf8)    if let modelT = JSONDeserializer<T>.deserializeFrom(json: jsonString) {      return modelT    }    return JSONDeserializer<T>.deserializeFrom(json: "{/"msg/":/"請求有誤/"}")!  }}

4.在MainClassViewModel中,使用已經封裝好的接口進行網絡請求,代碼如下:

import RxSwiftimport Moyaimport ObjectMapperimport HandyJSONimport RxCocoaclass MainClassViewModel {  private let provider = MoyaProvider<APIService>()  let disposeBag = DisposeBag()  var dataSource = BehaviorRelay<[MainClassModelMapObject_sub]>(value:[])  var networkError = BehaviorRelay(value: Error.self)}//MARK: -- 網絡extension MainClassViewModel {    //網絡請求-- ObjectMapper  func getClassListWithMapObject(){    provider.rx.request(.mainClassList).asObservable().mapObjectModel(MainClassModelMapObject.self).subscribe({ [unowned self] (event) in            switch event {      case let .next(classModel):        print("ObjectMapper -- 加載網絡成功")        self.dataSource.accept(classModel.data)              case let .error( error):        print("error:", error)        self.networkError.accept(error as! Error.Protocol)      case .completed: break      }    }).disposed(by: self.disposeBag)  }      //網絡請求-- HandyJSON  func getClassListWithMapHandyJson(){    provider.rx.request(.mainClassList).asObservable().mapHandyJsonModel(MainClassModel.self).subscribe({ [unowned self] (event) in            switch event {      case let .next(classModel):                print("HandyJSON -- 加載網絡成功")              case let .error( error):        print("error:", error)        self.networkError.accept(error as! Error.Protocol)      case .completed: break      }    }).disposed(by: self.disposeBag)  }  }

這里用了兩種方式,分別對 mainClassList API 接口進行了網絡請求,唯一不同的是,在得到到網絡請求回來數據的時候,一個是使用 mapObjectModel 把JSON 轉化成 Model ,一個是使用 mapHandyJsonModel 把 JSON轉化成Model ,由于我們使用的是不同的庫,把JSON 轉化成 Model,這兩種實現的方式還是有一些差別,下面是這兩種 Model 的具體實現方式:

其一、實現協議 Mappable

import UIKitimport ObjectMapperclass MainClassModelMapObject: Mappable {    var code:NSInteger?  var data:[MainClassModelMapObject_sub]!    required init?(map: Map) {}    func mapping(map: Map) {    code <- map["code"]    data <- map["data"]  }}class MainClassModelMapObject_sub: Mappable {    var ID:String?  var name:String?  var desc:String?  var imgUrl:String?  var gifUrl:String?  var isUpdate:Bool?  var backgroundGroup:NSInteger?    required init?(map: Map) {}    func mapping(map: Map) {        ID <- map["ID"]    name <- map["name"]    desc <- map["desc"]    imgUrl <- map["imgUrl"]    gifUrl <- map["gifUrl"]    isUpdate <- map["isUpdate"]    backgroundGroup <- map["backgroundGroup"]  }}

其二、實現協議 HandyJSON

import UIKitimport HandyJSONstruct MainClassModel: HandyJSON {  var code:NSInteger?  var data:[MainClassModel_sub]!}struct MainClassModel_sub: HandyJSON {    var ID:String?  var name:String?  var desc:String?  var imgUrl:String?  var gifUrl:String?  var isUpdate:Bool?  var backgroundGroup:NSInteger?}

5、以上是使用 RxSwift 進行網絡請求的分析,接下來看一個示例如何使用,在MainClassViewModel 中我們使用 dataSource 保存了網絡請求回來的數據,我們要在 ViewController里 用tableview 把這個數據展示出來,需要提前把數據源和TableView進行綁定,以下是示例代碼:

 //cell   viewModel.dataSource.bind(to: tableView.rx.items) { (tableView, row, element) in      let cell = tableView.dequeueReusableCell(withIdentifier: "MainClassTableViewCell", for: IndexPath(row: row, section: 0)) as! MainClassTableViewCell            cell.setModel(model: element)      // configure cell      return cell      }      .disposed(by: disposeBag)

在需要使用的地方,調用 方法 getClassListWithMapObject() 或者 getClassListWithMapHandyJson()

三、總結

這部分的內容,適合對RxSwift 有一定了解的小伙伴學習, 文章重點是 幫助大家學習和了解 RxSwift 網絡請求的相關知識,下面是一個寫好的demo

demo

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品一区二区三区免费视频| 久久精品国产亚洲一区二区| 国内免费久久久久久久久久久| 亚洲欧美一区二区三区久久| 国产精品成人av在线| 亚洲自拍偷拍福利| 狠狠久久五月精品中文字幕| 国产欧美欧洲在线观看| 亚洲精品女av网站| 91免费国产网站| 欧美成人免费全部观看天天性色| 欧美日韩国产激情| 国产69精品久久久久99| 日韩欧美极品在线观看| 97色在线视频| 91精品国产91久久久久久| 日韩中文字幕在线视频播放| 国产精品揄拍一区二区| 91精品国产综合久久香蕉922| 日韩在线视频中文字幕| 91国自产精品中文字幕亚洲| 亚洲第一中文字幕| 欧美激情欧美激情在线五月| 久久久噜噜噜久久久| 国产午夜精品视频| 亚洲精品成人免费| 欧美在线激情网| 4388成人网| 韩日精品中文字幕| 成人网页在线免费观看| 久久精品欧美视频| 7m精品福利视频导航| 日韩av在线不卡| 日韩欧美精品在线观看| 欧美性开放视频| 国产精品h片在线播放| 92国产精品视频| www.久久撸.com| 久久久久久亚洲精品中文字幕| 视频一区视频二区国产精品| 欧美午夜丰满在线18影院| 欧美老肥婆性猛交视频| 亚洲一区二区三区四区在线播放| 国产91精品久久久久| 一区二区三区美女xx视频| 国产视频精品免费播放| 人九九综合九九宗合| 伊人久久久久久久久久久| 色777狠狠综合秋免鲁丝| 91福利视频在线观看| 91超碰caoporn97人人| 国产精品青青在线观看爽香蕉| 中文字幕日韩精品有码视频| 亚洲欧美国产精品专区久久| 欧美在线视频网站| 久久久免费高清电视剧观看| 欧美日本中文字幕| 国产成人精品午夜| 精品成人69xx.xyz| 亚洲自拍偷拍第一页| 国内精品久久久久久影视8| 精品国产美女在线| 欧美精品一二区| 日韩国产欧美精品一区二区三区| 国产精品精品视频| 国产亚洲一区二区在线| 欧美成人网在线| 亚洲国产黄色片| 亚洲精品在线91| 国产日本欧美一区二区三区| 久久夜精品va视频免费观看| 欧美肥老妇视频| 国产精品美乳一区二区免费| 国内偷自视频区视频综合| 亚洲欧美一区二区三区久久| 不卡在线观看电视剧完整版| 久久精品视频va| 欧美与黑人午夜性猛交久久久| 欧美日韩成人在线播放| 美女性感视频久久久| 亚洲欧美日韩中文在线| 亚洲一区二区三区香蕉| 欧美性在线视频| 国产精品99久久久久久www| 欧美黑人xxx| 亚洲视频精品在线| 久久av.com| 亚洲乱码av中文一区二区| 欧美第一黄网免费网站| 日韩69视频在线观看| 久久久久久高潮国产精品视| 亚洲精品一区二区久| 2023亚洲男人天堂| 日韩欧美精品网址| 久久免费国产精品1| 精品国产一区二区三区在线观看| 欧美午夜激情视频| 亚洲自拍欧美另类| 国产精品久久不能| 欧美性猛交视频| 亚洲另类欧美自拍| 亚洲欧美一区二区三区情侣bbw| 欧美成人午夜影院| 91国内免费在线视频| 国产成人在线视频| 久久视频在线直播| 综合网日日天干夜夜久久| 日韩免费在线观看视频| 久久精品久久久久久国产 免费| 91精品视频免费观看| 国产精品私拍pans大尺度在线| www.久久色.com| 欧美精品在线观看91| 成人在线视频网站| 91精品综合视频| 精品国产一区二区三区久久狼黑人| 久久久女人电视剧免费播放下载| 国产精品久久久久国产a级| 亚洲精品成a人在线观看| 国产日韩换脸av一区在线观看| 欧美日韩中国免费专区在线看| 国产亚洲视频在线观看| 久久99久久99精品免观看粉嫩| 精品美女国产在线| 国产精品女人久久久久久| 日韩最新中文字幕电影免费看| 久久亚洲私人国产精品va| 亚洲天堂av在线免费| 欧美电影免费看| 日韩av大片在线| 精品日本高清在线播放| 国产精品视频在线播放| 国产欧洲精品视频| 国产精品视频久久久久| 96国产粉嫩美女| www.美女亚洲精品| 亚洲黄色av网站| 国产精品视频男人的天堂| 成人午夜激情免费视频| 夜色77av精品影院| 精品国内亚洲在观看18黄| 国产在线98福利播放视频| 国产精品成久久久久三级| 亚洲黄色av女优在线观看| 亚洲性线免费观看视频成熟| 97国产一区二区精品久久呦| 午夜精品免费视频| 中文字幕精品www乱入免费视频| 97精品久久久| 日韩一区视频在线| 91精品国产91久久久久久最新| 欧美激情视频三区| 精品福利在线看| 热re99久久精品国产66热| 国产精品国产三级国产aⅴ9色| 久久久久久这里只有精品| 亚洲精品在线观看www| 亚洲欧洲av一区二区| 国产香蕉97碰碰久久人人| 欧美高清在线视频观看不卡| 成人精品一区二区三区电影免费| 97在线日本国产| 疯狂做受xxxx高潮欧美日本| 日韩精品在线免费观看|