moya 与 RxSwift 使用

如在OC中使用AFNetworking一般,Swift我们用Alamofire来做网络库.而Moya在Alamofire的基础上又封装了一层:

1.关于moya

moya

官方说moya有以下特性-_-:

  • 编译时检查正确的API端点访问.
  • 使你定义不同端点枚举值对应相应的用途更加明晰.
  • 提高测试地位从而使单元测试更加容易.

2.开始

1.创建枚举API

就像这样:

enum APIManager {
case getNewsLatest//获取最新消息
case getStartImage// 启动界面图像获取
case getVersion(String)//软件版本查询
case getThemes//主题日报列表查看
case getNewsDetail(Int)//获取新闻详情
}

2.实现TargetType协议

就像这样:

extension APIManager: TargetType {

/// The target‘s base `URL`.
var baseURL: URL {

return URL.init(string: "http://news-at.zhihu.com/api/")!
}

/// The path to be appended to `baseURL` to form the full `URL`.
var path: String {

switch self {

case .getNewsLatest:
return "4/news/latest"

case .getStartImage://start-image 后为图像分辨率,接受任意的 number*number 格式, number 为任意非负整数,返回值均相同。
return "4/start-image/1080*1776"

case .getVersion(let version)://URL 最后部分的数字代表所安装『知乎日报』的版本
return "4/version/ios/" + version

case .getThemes:
return "4/themes"

case .getNewsDetail(let id):
return "4/news/\(id)"

}

}

/// The HTTP method used in the request.
var method: Moya.Method {

return .get
}

/// The parameters to be incoded in the request.
var parameters: [String: Any]? {

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
}

/// Whether or not to perform Alamofire validation. Defaults to `false`.
var validate: Bool {

return false
}

}

在这里,可以设置请求的参数,例如url……method……para等.

3.使用

Moya的使用非常简单,通过TargetType协议定义好每个target之后,就可以直接使用Moya开始发送网络请求了。就像这样:

let provider = MoyaProvider<APIManager>()
provider.request(.getNewsLatest) { result in
// do something with result
}

3.配合RxSwift

Moya本身已经是一个使用起来非常方便,能够写出非常简洁优雅的代码的网络封装库,但是让Moya变得更加强大的原因之一还因为它对于Functional Reactive Programming的扩展,具体说就是对于RxSwiftReactiveCocoa的扩展,通过与这两个库的结合,能让Moya变得更加强大。我选择RxSwift的原因有两个,一个是RxSwift的库相对来说比较轻量级,语法更新相对来说比较少,我之前用过ReactiveCocoa,一些大版本的更新需求重写很多代码,第二个更重要的原因是因为RxSwift背后有整个ReactiveX的支持,里面包括JavaJS.NetSwiftScala,它们内部都用了ReactiveX的逻辑思想,这意味着你一旦学会了其中的一个,以后可以很快的上手ReactiveX中的其他语言。

Moya提供了非常方面的RxSwift扩展:

let provider = RxMoyaProvider<APIManager>()
provider.request(.getNewsLatest)
.filterSuccessfulStatusCodes()
.mapJSON()
.subscribe(onNext: { (json) in
//do something with posts
print(json)
})
.addDisposableTo(disposeBag)

解释一下:

  • RxMoyaProviderMoyaProvider的子类,是对RxSwift的扩展
  • filterSuccessfulStatusCodes()MoyaRxSwift提供的扩展方法,顾名思义,可以得到成功地网络请求,忽略其他的
  • mapJSON()也是Moya RxSwift的扩展方法,可以把返回的数据解析成 JSON 格式
  • subscribe 是一个RxSwift的方法,对经过一层一层处理的 Observable 订阅一个 onNext 的 observer,一旦得到 JSON 格式的数据,就会经行相应的处理
  • addDisposableTo(disposeBag) 是 RxSwift 的一个自动内存处理机制,跟ARC有点类似,会自动清理不需要的对象。

4.配合HandyJSON

在实际应用过程中网络请求往往紧密连接着数据层(Model),具体地说,在我们的这个例子中,一般我们需要建立一个类用来统一管理数据,然后把得到的 JSON 数据映射到数据层(Model)。

struct MenuModel: HandyJSON {
var others: [ThemeModel]?

}

struct ThemeModel: HandyJSON {

var color: String?
var thumbnail: String?
var id: Int?
var description: String?
var name: String?
}

然后创建ViewModel类,创建具体请求方法:

class MenuViewModel {

private let provider = RxMoyaProvider<APIManager>()
var dispose = DisposeBag()

func getThemes(completed: @escaping (_ menuModel: MenuModel) -> ()){

provider
.request(.getThemes)
.mapModel(MenuModel.self)
.subscribe(onNext: { (model) in

completed(model)
}, onError: { (error) in

}, onCompleted: nil, onDisposed: nil).addDisposableTo(dispose)

}

}

这里解释一下:
我这里是将请求的数据通过闭包传了出去,当然也可以不那么做.个人喜好问题..

这里是为 RxSwift 中的 ObservableType和 Response写一个简单的扩展方法 mapModel,利用我们写好的Model 类,一步就把JSON数据映射成 model

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)!
}
}

文章转载自 Three_Zhang‘s Blog ,以做记录

时间: 2024-08-28 02:44:44

moya 与 RxSwift 使用的相关文章

RxSwift + Moya + ObjectMapper

https://www.jianshu.com/p/173915b943af use_frameworks! target 'RXDemo' do pod 'RxSwift' pod 'RxCocoa' pod 'Moya-ObjectMapper/RxSwift' pod 'Moya/RxSwift' end import Moya let DouBanProvider = MoyaProvider<DouBanAPI>() public enum DouBanAPI { case chan

Swift网络请求(Moya篇)

在使用Alamofire进行网络请求的时候,相信大部分的同学都会封装一个抽象的NetworkLayer,如"APIManager" 或者 "NetworkModel"等等.但是位置业务功能增加,会渐渐混合各种请求,不够清晰,而Moya能很好地解决这类问题.Moya在Alamofire基础上进行封装,是一个允许高度自定义的网络层,可以根据具体的需求进行接口的设置.具体的介绍可以参考Moya的官方链接,结构图如下: 接下来就介绍一下Moya的一些常见的用法: (一)根据

RxSwift 实战操作【注册登录】

前言 看了前面的文章,相信很多同学还不知道RxSwift该怎么使用,这篇文件将带领大家一起写一个 注册登录(ps:本例子采用MVVM)的例子进行实战.本篇文章是基于RxSwift3.0写的,采用的是Carthage第三方管理工具导入的RxSwift3.0,关于Carthage的安装和使用,请参考Carthage的安装和使用. 最终效果 下载Demo点我 前提准备 首先请大家新建一个swift工程,然后把RxSwift引入到项目中,然后能够编译成功就行. 然后我们来分析下各个界面的需求: 注册界面

ReactiveCocoa / RxSwift 笔记一

原创:转载请注明出处 ReactiveCocoa / RxSwift Native app有很大一部分的时间是在等待事件发生,然后响应事件,比如 1.等待网络请求完成, 2.等待用户的操作, 3.等待某些状态值的改变等等, 等这些事件发生后,再做进一步处理 但是这些等待和响应,并没有一个统一的处理方式.Delegate, Notification, Block, KVO, 常常会不知道该用哪个最合适.有时需要chain或者compose某几个事件,就需要多个状态变量,而状态变量一多,复杂度也就上

RxSwift 系列(九)

前言 看完本系列前面几篇之后,估计大家也还是有点懵逼,本系列前八篇也都是参考RxSwift官方文档和一些概念做的解读.上几篇文章概念性的东西有点多,一时也是很难全部记住,大家脑子里面知道有这么个概念就行,用的时候,再来查阅一番,慢慢就掌握了. 本篇主要来深入了解一些RxSwift实战中用到的一些重要知识点,这里面有很多自己的理解,所以不免会有一些错误的地方,还请大家多多交流,如有发现错误的地方,欢迎评论. 概念 Rx系列的核心就是Observable Sequence这个相信大家心中已经有所了解

RxSwift 系列(八)

前言 本篇文章我们将学习RxSwift中的错误处理,包括: catchErrorJustReturn catchError retry retry(_:) catchErrorJustReturn 遇到error事件的时候,返回一个值,并且结束.更多详情 let disposeBag = DisposeBag() let sequenceFail = PublishSubject<String>() sequenceFail.catchErrorJustReturn("??"

RxSwift 系列(一)

为什么使用RxSwift? 我们编写的代码绝大多数都涉及对外部事件的响应.当用户点击操作时,我们需要编写一个@IBAction事件来响应.我们需要观察通知,以检测键盘何时改变位置.当网络请求响应数据时,我们必须提供闭包来执行.我们使用KVO来检测变量的变化.所有这些不同的系统使我们的代码增加了不必要地复杂.如果有一个一致的系统来处理我们的所有的调用/响应代码,难道不是更好吗?Rx就是这样一个系统. RxSwift是用于大多数主要语言和平台的响应扩展(即Rx)的正式实现. 概念 每一个Observ

Swift &#160;之 RxSwift(1)

RxSwift 官方文档结构 Introduction: Subjects Transforming Observables Filtering Observables Combining Observables Error Handing Operators Observable Utility Operators Conditional and Boolean Operators Mathematical and Aggregate Operators Connectable Observa

RxSwift 系列(三)

RxSwift 系列(三) -- Combination Operators 前言 本篇文章将要学习如何将多个Observables组合成一个Observable.Combination Operators在RxSwift中的实现有五种: startWith merge zip combineLatest switchLatest startWith 在Observable释放元素之前,发射指定的元素序列.更多详情上面这句话是什么意思呢?翻译成大白话就是在发送一个东西之前,我先发送一个我指定的东