zoukankan      html  css  js  c++  java
  • Moya 与 RxSwift 使用

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

    1.关于moya

    moyamoya

    官方说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)!
    }
    }

    文章转载自  ,以做记录

  • 相关阅读:
    ASP.NET2.0中GridView加入CheckBox实现全选!
    恢复误删数据(SQL Server 2000)--Log Explorer
    url传递中文的解决方案总结
    JavaScript : Tip提示框。
    合并GridView中某列相同信息的行
    ASP.NET 2.0服务器控件与form runat=server标记 !!
    实现天气预报类···························
    正则抓取SINA天气预报数据!!!
    ASP.NET 2.0中将 GridView 导出到 Excel 文件中
    GridView控件修改、删除示例(修改含有DropDownList控件)
  • 原文地址:https://www.cnblogs.com/L-vincen/p/6944073.html
Copyright © 2011-2022 走看看