Moya使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Moya使用相关的知识,希望对你有一定的参考价值。

参考技术A 关于Moya的官方可参考:  点击查看

Moya官方使用下图来对比直接使用Alamofire和用Moya的区别(左:Alamofire,右:Moya)

Moya包含模块:

Moya流程图:

Moya使用

在项目中可通过Pod,Carthage等方式引入Moya

CocoaPods :

Carthage :

Moya使用介绍:

Targets

使用Moya,首先需要定义一个target(通常是继承TargetType协议的枚举变量),接下来,只需要处理这些targets(即:希望调用API完成的操作)

Targets必须继承TargetType

TargetType协议要求在枚举中定义一个baseURL属性。注意:baseURL的值不会取决于self的值,而是返回一个固定值(如果有多个API baseURL,需要使用多个枚举和Moya providers)

例如:

做完上面的 TargetType 之后,构造 Provider 就很简单啦

Provider

provider是网络请求的提供者,所有的网络请求都通过provider来调用。

通过枚举来指定要访问的具体API

provider最简单的创建方法:

通过Moya源码可知MoyaProvider是一个实现了MoyaProviderType协议的公开类,需要传入一个遵循TargetType协议的对象名,这是泛型的常规用法

简单配置后就可以使用

request方法返回一个Cancellable,它有一个可以取消request的公共的方法。

MoyaProvider的构造方法如下:

了解Moya的高级用法,需要先了解清晰MoyaProvider构造方法的所有参数

1、endpointClosure 一个endpoints闭包,它可以将target转换成具体的EndPoint实例

这样初始化MoyaProvider的时候,不需要在说明target的具体类型,Swit会根据endpointClosure推断。

MoyaProvider.defaultEndpointMapping 为默认实现

2、requestClosure

可以将Endpoint转换为NSURLRequest

3、stubClosure

它返回一个.Never(默认),或.Immediate,或.Delayed(seconds),可以延迟这个stub模拟请求(具体n秒)。例如:.Delayed(1),会把每个请求延迟1秒

这样的好处就是当需要模拟不同于其他的特殊请求是,可以编写自己的闭包:

4、callbackQueue

可指定callback的Queue

5、session

可针对URLSessionConfiguration进行配置

6、plugins

插件数组,它们在发起请求之前和收到返回之后调用,比如:开始网络请求之前的NetworkActivityPlugin, 结束网络之后的日志NetworkLoggerPlugin

使用方式:

7、trackInflights

是否要跟踪重复网络请求

MultiTarget

正常情况下,都是一个target对应一个Provider

 有时候程序会根据业务逻辑拆分成多个target,这样target可能就会有多个,如果有多个target我们就创建多少个Provider,会让程序的逻辑复杂化。

 特别是当它们使用同样的plugings或closures时,又要做一些额外的工作去维护。

 那么借助MultiTarget,可以让多个target都使用相同的Provider

例子:

定义Target

Provider定义

1对1 使用方式

 使用多个target的Provider可以如下方式定义

Provider使用

一对一 使用方式

 使用多个target的Provider,如下方式

Moya针对返回结果的处理:

Moya 会将 Alamofire 成功或失败的响应包裹在 Result 枚举中返回,具体值如下:

         .success(Moya.Response):成功的情况。我们可以从 Moya.Response 中得到返回数据(data)和状态(status )

         .failure(MoyaError):失败的情况。这里的失败指的是服务器没有收到请求(例如可达性/连接性错误)或者没有发送响应(例如请求超时)。我们可以在这里设置个延迟请求,过段时间重新发送请求。

针对错误的类型,可以通过switch语句判断具体的MoyaError错误类型:

使用 Moya 将参数附加到每个网络调用

【中文标题】使用 Moya 将参数附加到每个网络调用【英文标题】:Append parameters to each network call with Moya 【发布时间】:2018-11-09 13:03:19 【问题描述】:

如何使用 (Rx) Moya 将默认请求参数(例如 AppID)附加到每个 API 调用?

【问题讨论】:

检查this 和this。他们应该可以帮助您找到自己的方式。 【参考方案1】:

Moya 中的Endpoint 类有adding(newHTTPHeaderFields:),它需要一个字典,在这里您可以提供您的附加http 标头,这些标头将为每个请求发送。文档link

let endpointClosure =  (target: TargetType) -> Endpoint in
    let defaultEndpoint = MoyaProvider.defaultEndpointMapping(for: target)
    return defaultEndpoint.adding(newHTTPHeaderFields: ["AppID": "MY_APP_ID"])

let provider = MoyaProvider<TargetType>(endpointClosure: endpointClosure)

【讨论】:

谢谢!但这并不能解决附加默认参数的问题。据我所知,该代码仅允许附加 HTTP 标头。【参考方案2】:
    //Create a BaseMoyaProvider class and add default paramaters 

    import Moya
    import Result
    import SwiftyJSON

    class BaseMoyaProvider 
      static func create<T: TargetType>(service: T.Type) -> (T)->(Endpoint) 
        let closure =  (target: T) -> Endpoint in
          let endpoint = MoyaProvider.defaultEndpointMapping(for: target)

          switch endpoint.task 
          case .requestParameters(
            let _parameters,
            let _encoding):

            let parameters = _parameters
              .appending([
                "AppID" : "XXXXXXXXXXX"
                ])

            let task = Task.requestParameters(
              parameters: parameters,
              encoding: _encoding
            )

            return endpoint
              .replacing(task: task)
          default: return endpoint
          `enter code here`
        
        return closure
      
     

//Extend MoyaProvider class

extension MoyaProvider 
  static func build() -> MoyaProvider<Target> 
    let provider = BaseMoyaProvider
      .create(service: Target.self)

    return MoyaProvider<Target>(
      endpointClosure: provider,
      plugins: [ ApiLogger() ]
    )
  

  // MARK: Request
  func rx_request<T: Mappable>(_ target: Target) -> Observable<T> 
    return Observable.create( (observer) -> Disposable in
      let request = self.request(target, completion:  (result) in
        //Handle response
      )
      return Disposables.create 
        request.cancel()
      
    )
  

【讨论】:

以上是关于Moya使用的主要内容,如果未能解决你的问题,请参考以下文章

使用 Moya 获取响应标头

使用 Moya 处理缓存

使用 Moya 刷新身份验证令牌

理解 Realm、Moya 和 ObjectMapper

使用 Moya 将参数附加到每个网络调用

使用 moya 发送一个 swiftyjson 数组