Moya集锦

Moya库是对Alamofire库的二次封装封装.

对于Alamofire咱们在这就不做多余赘述了,感兴趣的可以去官网看一下.下面我们进入这次的主题-Moya.

Moya 的基本用法是创建请求枚举类型,然后实现TargetType协议.比较简单、霸气.当然这不是我们今天说的重点,下来的开始画重点了.

如果一个app有一百个或者更多的请求时,如何优雅的使用Moya库呢.首先,Moya本身没问题,那么我们都是什么样的使用姿势呢?

第一种:

创建一个大的API ,然后里面创建一百个API枚举类型,然后各种检查,各种协议实现.这一种属于最基本的用法!什么叫基本?就是完成了工作,至于工作完成的内涵,则就不登大雅之堂了.

第二种:

每一个模块创建一个大的API,然后里面创建了五十个枚举类型,然后各种检查,各种协议实现.这一种属于有思想的用法!最起码我们大家都去想了,也做出了自己的努力

那么问题来了?有没有更合适的方案呢!!!

划重点

那就是我们今天要说的方案了.
官网的各种用法,我就不做详细说明了,相信大家都有自己的开发经验.如果说不是那两种方案,让你设计一下,你会考虑从什么地方优化呢?我们大多都会想到如何去缩减冗余及如何优化内存和性能什么的.至于性能这块咱们就不浪费口舌了,那么如何去缩减冗余呢?

在这里我们采用三层设计方案来解决项目网络层优化问题.

第一层:数据处理层 - LTMNetworkDeal

在这里有我们的数据处理中心,上代码

dealResult(targetName: String,result: Result<Response, MoyaError>, successClosure:((_ result: Any) -> ())? = nil, failureClosure:((_ errorCode: Int, _ errorMessage: String) ->())? = nil)

数据处理入口,

switch moyaResponse.statusCode {
        case 200:
            guard let resultDic: [String: Any] = try? moyaResponse.mapJSON() as? [String : Any],
                let code: Int = resultDic["code"] as? Int
                else { return }
            print("统一显示返回数据 \(resultDic)")
            switch code {
            case 200:
                guard let systemEntity: [String: Any] = resultDic["entity"] as? [String : Any] else {
                    successClosure?(self.success200Deal(response: resultDic, targetName: targetName ))
                    return
                }
                successClosure?(self.success200Deal(response: systemEntity, targetName: targetName ))
            case 400:
 if let errorServerMes = resultDic["message"]{
                    failureClosure?(400, self.error400Deal(response: errorServerMes) ?? "服务器异常,未确认错误信息")
                }
            case 403:
                if let errorServerMes = resultDic["message"]{
                    failureClosure?(403, self.error403Deal(response: errorServerMes) ?? "服务器异常,未确认错误信息")
                }
            case 500:
                if let errorServerMes = resultDic["message"]{
                    failureClosure?(500, self.error500Deal(response: errorServerMes) ?? "服务器异常,未确认错误信息")
                }
            default:
                print("errorServerMes")
            }
        case 404:
            failureClosure?(moyaResponse.statusCode,"api地址错误,请内部开发人员修改后重试")
        case 500:
            failureClosure?(moyaResponse.statusCode,"服务器响应错误,请内部开发人员修改后重试")
        case 502:
            failureClosure?(moyaResponse.statusCode, self.error502Deal(response: "errorServerMes") ?? "服务器异常,未确认错误信息")
        default:
            failureClosure?(moyaResponse.statusCode, self.error500Deal(response: "errorServerMes") ?? "服务器异常,未确认错误信息")
            break

数据详细处理阶段,

 func success200Deal(response: [String : Any], targetName: String) -> Any{
    
    
    return response
}

func error400Deal(response: Any) -> String?{
    if let errorInfo:[String: Any] = response as? [String : Any]{
        
        return errorInfo["message"] as? String
    }else{
        
        return "error400Deal"
    }
}

func error403Deal(response: Any) -> String?{
    if let errorInfo:[String: Any] = response as? [String : Any]{
        
        return errorInfo["message"] as? String
    }else{
        
        return "error403Deal"
    }
}

func error500Deal(response: Any) -> String?{
    if let errorInfo:[String: Any] = response as? [String : Any]{
        
        return errorInfo["message"] as? String
    }else{
        
        return "error500Deal"
    }
}

func error502Deal(response: Any) -> String?{
    if let errorInfo:[String: Any] = response as? [String : Any]{
        
        return errorInfo["message"] as? String
    }else{
        
        return "error502Deal"
    }
}
func errorRequestDeal(response: Any) -> String{
    
    print("柯南 Deal errorRequestDeal info response success response - \(response)")
    
    return "errorRequestDeal"
}
第二层:API层 - LTMMoyaLoginApiService、LTMMoyaHomeApiService...

这个就不详细赘述了,和Moya上基本一致.

在使用上,可以采用一些省略处理.
EG:

var task: Task {
    switch self {
    case .login:
        return .requestParameters(parameters: param, encoding: JSONEncoding.default)
    default:
        return .requestParameters(parameters: param, encoding: URLEncoding.default)
    }

合理使用default,你会发现你会省很多代码.
!!! 但是不建议path协议实现采用,防止接口忘记写的情况

第三层:网络处理层 - LTMMoyaNetworkManager:LTMNetworkDeal

网络层继承于第一层数据处理层LTMNetworkDeal,然后在使用的时候采用如下方案

//MARK: - 登录请求
private var loginProvider = MoyaProvider<LTMMoyaLoginApiService>(plugins: [NetworkLoggerPlugin()])

public func merchantLoginModuleRequest(target: LTMMoyaLoginApiService, targetName: String, successClosure:((_ result: Any) -> ())? = nil, failureClosure:((_ errorCode: Int, _ errorMessage: String) ->())? = nil){
    loginProvider.request(target) { (result) in
        self.dealResult(targetName: targetName, result: result,successClosure: successClosure, failureClosure: failureClosure)
    }
}

//MARK: - 首页接口
private var homeProvider = MoyaProvider<LTMMoyaHomeApiService>(plugins: [NetworkLoggerPlugin()])

public func merchantSalesApplyModuleRequest(target: LTMMoyaHomeApiService, targetName: String, successClosure:((_ result: Any) -> ())? = nil, failureClosure:((_ errorCode: Int, _ errorMessage: String) ->())? = nil){
    homeProvider.request(target) { (result) in
        self.dealResult(targetName: targetName, result: result,successClosure: successClosure, failureClosure: failureClosure)
    }
}

这样的话基本上把整个网络拆开了,而且更有条理性.
这块有一点需要简要说明一下,本地采用的时候传递了一个targetName,这个是做后续扩展使用的.还会持续更新.至于如何使用,大家其实心中已经有数了吧,好了,让我们下次揭晓咯.

说一千道一万,不如Demo转一转.
希望大家喜欢哈.

2020.05.18补充:

Moya续已经把我们遗留的补充了,目前已经可以完整使用了哈.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350