1壁肋、Moya的使用
1属愤、創(chuàng)建枚舉API
enum APIManager {
case News
}
2、實現(xiàn)TargetType協(xié)議
extension APIManager: TargetType {
//請求地址
var baseURL: URL {
return URL(string: "http://api.dantangapp.com")!
}
//每個接口的api
var path: String {
switch self {
case .News:
return "/v2/items"
}
}
//每個接口的請求方式
var method: Moya.Method {
switch self {
case .News:
return .get
}
}
//每個接口的參數(shù)
var parameters: [String: Any]? {
switch self {
case .News:
return nil
}
}
/// The method used for parameter encoding.
var parameterEncoding: ParameterEncoding {
return URLEncoding.default
}
/// Provides stub data for use in testing.
var sampleData: Data {
return "".data(using: String.Encoding.utf8)!
}
/// The type of HTTP task to be performed.
var task: Task {
return .request
}
var validate: Bool {
return false
}
}
3酸役、發(fā)送網(wǎng)絡(luò)請求
let provider = MoyaProvider<APIManager>()
provider.request(.News) { result in
print(result)
}
2住诸、添加RXSwift
Moya添加了對于RxSwift的接口支持,對于上邊的網(wǎng)絡(luò)請求可以寫成這樣:
let provider = RxMoyaProvider<APIManager>()
var disposeBag = DisposeBag()
provider.request(.News)
.filterSuccessfulStatusCodes()
.mapJSON()
.subscribe(onNext: { (json) in
print(json)
})
.addDisposableTo(disposeBag)
解釋一下:
RxMoyaProvider是MoyaProvider的子類涣澡,是對RxSwift的擴展
filterSuccessfulStatusCodes()是Moya為RxSwift提供的擴展方法贱呐,顧名思義,可以得到成功地網(wǎng)絡(luò)請求入桂,忽略其他的
mapJSON()也是Moya RxSwift的擴展方法奄薇,可以把返回的數(shù)據(jù)解析成 JSON 格式
subscribe 是一個RxSwift的方法,對經(jīng)過一層一層處理的 Observable 訂閱一個 onNext 的 observer抗愁,一旦得到 JSON 格式的數(shù)據(jù)馁蒂,就會經(jīng)行相應(yīng)的處理
addDisposableTo(disposeBag) 是 RxSwift 的一個自動內(nèi)存處理機制,跟ARC有點類似蜘腌,會自動清理不需要的對象沫屡。
3、+ Model (HandyJSON)
struct ListModel: HandyJSON {
var data: ListItemModel?
}
struct ListItemModel: HandyJSON {
var items: [FirstModel]?
}
struct FirstModel: HandyJSON {
var data: DataModel?
}
struct DataModel: HandyJSON {
var cover_image_url: String?
var description: String?
var name: String?
}
4撮珠、+ MVVM
MVVM(Model-View-ViewModel)可以把數(shù)據(jù)的處理邏輯放到 ViewModel沮脖, 從而大大減輕了 ViewController 的負(fù)擔(dān),是 RxSwift 中最常用的架構(gòu)邏輯芯急。
import Moya
import RxSwift
import RxDataSources
class BaseViewModel: NSObject {
let provider = RxMoyaProvider<APIManager>()
var disposeBag = DisposeBag()
}
class FirstViewModel: BaseViewModel {
func getNewsData(completed: @escaping (_ model: ListModel) -> ()) {
provider.request(.News)
.mapModel(ListModel.self)
.subscribe(onNext: { model in
completed(model)
}, onError: { error in
}, onCompleted: nil, onDisposed: nil)
.addDisposableTo(disposeBag)
}
這里是為 RxSwift 中的 ObservableType和 Response寫一個簡單的擴展方法 mapModel勺届,利用我們寫好的Model 類,一步就把JSON數(shù)據(jù)映射成 model
import RxSwift
import Moya
import HandyJSON
extension ObservableType where E == Response {
public func mapModel<T: HandyJSON>(_ type: T.Type) -> Observable<T> {
return flatMap { response -> Observable<T> in
return Observable.just(response.mapModel(T.self))
}
}
}
extension Response {
func mapModel<T: HandyJSON>(_ type: T.Type) -> T {
let jsonString = String.init(data: data, encoding: .utf8)
return JSONDeserializer<T>.deserializeFrom(json: jsonString)!
}
}
5娶耍、在UITableView中的使用
import RxCocoa
import RxSwift
import RxDataSources
import Moya
class FirstViewController: UIViewController {
let disposeBag = DisposeBag()
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String,FirstModel>>()
let dataArray = Variable([SectionModel<String, FirstModel>]())
let viewModel = FirstViewModel()
lazy var tableView: UITableView = {
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: kScreenW, height: kScreenH), style: .plain)
tableView.backgroundColor = BaseColor.BackGroundColor
tableView.separatorStyle = .none
tableView.register(FirstTableViewCell.self, forCellReuseIdentifier: "cell")
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
title = "First"
view.backgroundColor = .white
view.addSubview(tableView)
//獲取數(shù)據(jù)
viewModel.getNewsData { (model) in
self.dataArray.value = [SectionModel(model: "", items: (model.data?.items)!)]
}
//設(shè)置cell
dataSource.configureCell = { _, tableView, indexPath, model in
let cell = FirstTableViewCell(style: .default, reuseIdentifier: "cell")
cell.model = model.data
return cell
}
//綁定數(shù)據(jù)源
dataArray.asObservable().bind(to: tableView.rx.items(dataSource: dataSource))
.addDisposableTo(disposeBag)
//設(shè)置delegate
tableView.rx.setDelegate(self).disposed(by: disposeBag)
//cell點擊事件
tableView.rx
.modelSelected(FirstModel.self)
.subscribe(onNext: { (model) in
self.navigationController?.pushViewController(SecondViewController(), animated: true)
})
.addDisposableTo(disposeBag)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension FirstViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0.01
}
}
在UITableViewCell中實現(xiàn)數(shù)據(jù)
var model: DataModel? {
didSet {
titleLabel.text = model?.description
icomImageView.kf.setImage(with: URL(string: (model?.cover_image_url)!))
fromLabel.text = model?.name
}
}
6免姿、在UICollectionView中的使用
同上,只用把dataSource改變一下就行了
let dataSource = RxCollectionViewSectionedReloadDataSource<SectionModel<String,FirstModel>>()
【RxSwift系列】RXSwift在UITableView中使用(一)http://www.reibang.com/p/4d9447d5278a
【RxSwift系列】RxSwift下基于MJRefresh實現(xiàn)下拉刷新榕酒,上拉加載(三)http://www.reibang.com/p/6f14d6a7cb96