1、Moya的使用
1、创建枚举API
enum APIManager {
case News
}
2、实现TargetType协议
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
}
}
//每个接口的参数
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、发送网络请求
let provider = MoyaProvider<APIManager>()
provider.request(.News) { result in
print(result)
}
2、添加RXSwift
Moya添加了对于RxSwift的接口支持,对于上边的网络请求可以写成这样:
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提供的扩展方法,顾名思义,可以得到成功地网络请求,忽略其他的
mapJSON()也是Moya RxSwift的扩展方法,可以把返回的数据解析成 JSON 格式
subscribe 是一个RxSwift的方法,对经过一层一层处理的 Observable 订阅一个 onNext 的 observer,一旦得到 JSON 格式的数据,就会经行相应的处理
addDisposableTo(disposeBag) 是 RxSwift 的一个自动内存处理机制,跟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)可以把数据的处理逻辑放到 ViewModel, 从而大大减轻了 ViewController 的负担,是 RxSwift 中最常用的架构逻辑。
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数据映射成 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)
//获取数据
viewModel.getNewsData { (model) in
self.dataArray.value = [SectionModel(model: "", items: (model.data?.items)!)]
}
//设置cell
dataSource.configureCell = { _, tableView, indexPath, model in
let cell = FirstTableViewCell(style: .default, reuseIdentifier: "cell")
cell.model = model.data
return cell
}
//绑定数据源
dataArray.asObservable().bind(to: tableView.rx.items(dataSource: dataSource))
.addDisposableTo(disposeBag)
//设置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中实现数据
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.jianshu.com/p/4d9447d5278a
【RxSwift系列】RxSwift下基于MJRefresh实现下拉刷新,上拉加载(三)http://www.jianshu.com/p/6f14d6a7cb96