Moya 与 RxSwift 使用
2020-02-16 09:43
856 查看
如在OC中使用AFNetworking一般,Swift我们用Alamofire来做网络库.而Moya在Alamofire的基础上又封装了一层:
1.关于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的扩展,具体说就是对于
RxSwift和
ReactiveCocoa的扩展,通过与这两个库的结合,能让
Moya变得更加强大。我选择
RxSwift的原因有两个,一个是
RxSwift的库相对来说比较轻量级,语法更新相对来说比较少,我之前用过
ReactiveCocoa,一些大版本的更新需求重写很多代码,第二个更重要的原因是因为
RxSwift背后有整个
ReactiveX的支持,里面包括
Java,
JS,
.Net,
Swift,
Scala,它们内部都用了
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)
解释一下:
-
RxMoyaProvider
是MoyaProvider
的子类,是对RxSwift
的扩展 -
filterSuccessfulStatusCodes()
是Moya
为RxSwift
提供的扩展方法,顾名思义,可以得到成功地网络请求,忽略其他的 -
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 ,以做记录
转载于:https://www.cnblogs.com/L-vincen/p/6944073.html
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- Swift学习笔记-数字
- Swift学习笔记-空格
- Swift学习笔记-条件判断
- 自学 iOS - 三十天三十个 Swift 项目 第一天
- Swift 基础语法入门(一)
- error in Swift. “Consecutive Declarations On A Line Must Be Separated By ';'”
- Swift3.0 更新后出现比较运算符方法
- Apple Swift编程
- Swift中自动生成中间带小头像的二维码
- swift懒加载以及只读属性
- UItextField 用法(swift)
- 详解Swift中的iOS设计模式
- swift 小记
- Swift的74个常用内置函数介绍
- Swift基础小结_2
- Swift学习1---Swift语言概览
- swift 如何获取webView的内容高度
- Swift 为你的webView定制标题
- swift 定制自己的Button样式
- swift webView 提出这样的要求你能忍吗?