美文网首页
Moya + ObjectMapper 扩展及封装

Moya + ObjectMapper 扩展及封装

作者: 旋律breeze | 来源:发表于2018-08-30 14:26 被阅读0次

        Moya 是一个基于Alamofire的 面向协议 插件化的 网络库,调用者可以通过实现TargetType协议和方便的发起网络调用,而且可以根据不同的需要定制各种插件进行初始化。

        但是在实际使用过程中仍有一些个问题

    1 TargetType 协议变量太多,调用方实际只主要关心 task, path 这两个,  BaseUrl不应该暴露给调用方,这些都可以通过扩展TargetType 来实现,但是若想加入其它功能,比方说加入缓存功能,加入token,或者加入大量公共参数,这些该如何实现,怎么实现比较好?

    2 Moya 网络返回的是Moya.Response 类型的数据,实际开发中大量使用自定义的Struct 作为 数据类型,虽然有ObjectMapper 可以很方便的做数据转换,但每次都要在闭包里做一次转换,可以直接返回一个Struct对象不是更好吗?

         解决办法 

    1  继承TargetType, 创建一个新的Target协议, 加入自定义参数,同时隐藏不必要参数,比如想加入缓存功能,

         1 先定义缓存协议

    publicenumRequestCachePolicy{

        /// 忽略缓存,仅加载网络数据

        casereloadIgnoringLocalCacheData

        /// 只加载缓存数据

        caseretutnCacheDataDontLoad

        /// 先加载缓存然后网络数据

        caseretutnCacheDataThenLoad

    }

    public protocol CacheType {

        // 是否需要缓存

        varneedCache:Bool{get}

        // 缓存资源的标示

        varcacheId: () ->String{get}

        // 加载缓存策略

        varcachePolicy:RequestCachePolicy{get}

    }

     2  创建新的TargetType, 并且加入自定义参数,同时 

    public protocol XLTargetType: TargetType, CacheType, AccessTokenAuthorizable{

        /// 具体业务参数

        varparameters: [String:Any]? {get}

    }

    3 重写MoayProvider 支持缓存功能

      详见 Github

    2 第二个问题,有三个思路

       1  扩展Moya.Response类型,增加转换函数,这是基础,每次请求后多家一行转换函数

           funcmapCommonModel()throws->T{

            do{

                letjsonObj =  tryJSONSerialization.jsonObject(with:data, options: .allowFragments)

                letobject =Mapper().map(JSONObject: jsonObj)

                ifobject ==nil{

                    throwYLError.mapNilError

                }

                returnobject!

            }catchYLError.mapNilError  {

                throwYLError.mapNilError

            }catch{

                throwYLError.responseError

            }

        }

       2 将返回的数据类型做成 associatedtype 定义在新建的TargetType中,并重写MoyaProvider,这样请求直接返回的就是关联类型指定的数据类型, 但这样会造成另外一个问题:没有办法批量写Api代码,毕竟每个TargetType协议只支持一个associatedtype

    public protocol YLTargetType: TargetType, CacheType, AccessTokenAuthorizable{

        /// 返回数据类型, 这种写法理论上没问题,但实际用起来很麻烦,没办法批量组织api

        associatedtyperesponseModelType:Mappable

        /// 具体业务参数

        varparameters: [String:Any]? {get}

    }

    // 调用

    let provider = DataProvider()    

     let sequence1 = provider.rx.requestModel(.home)

      let sequence2 = provider.rx.requestResult(.home)

    3 将数据类型做成provider.request() 函数的泛型,这样也可以直接返回数据类型, 这也是最好的一种

    publicprotocolXLProviderType:AnyObject{

        associatedtype Target: XLTargetType

        funcrequest(_target:Target, callbackQueue:DispatchQueue?, progress:Moya.ProgressBlock?, completion:@escaping(_result:Result,_isCache:Bool) ->Void) ->Cancellable

    }

    // 调用

      let provider = XLProvider()      

    let userSequence = provider.rx.requestResult(.user) as Observable>

     详见Github

     最后 

        第三方虽然好用,但是对第三方包装一层仍然是必要的,

    1   万一没有,发生AF2.0 到 AF3.0哪样的重大变动,那就炸了 

    2  第三方通用性太好,但不贴近实际项目,根绝实际需求自定制一下,对于开发者会友好的多,

    3  面向协议和插件化是网络库最好的选择,  关于插件没有细说,代码里有

    相关文章

      网友评论

          本文标题:Moya + ObjectMapper 扩展及封装

          本文链接:https://www.haomeiwen.com/subject/ujirwftx.html