use MultiTarget for multiple targets (高级用法--使用MultiTarget)--Moya文档

Advanced usage - use MultiTarget for multiple targets using the same Provider(高级用法--使用MultiTarget(为多个target使用同样的Provider)

当你有很多个endpoints时,你可能会得到一个很长的provider并且在几百个case里面切换.当然,你可以把这些逻辑分割到多个target中,但你不得不使用多个providers.这会使你的app逻辑复杂化,如果你想为每个provider使用相同的plugins/closures,需要额外的工作来管理它.然而,我们可以使用MutiTarget这个内置枚举,它可以很容易的使用,而且能帮我们解决上面的问题.

首先,我们定义一个将使用多个target的provider

let provider = MoyaProvider<MultiTarget>()

然后把请求

provider.request(.zen) { result in
// do something with `result`
}

替换成

provider.request(MultiTarget(GitHub.zen)) { result in
// do something with `result`
}

改造完毕!相当的简单.如果你有很多想分割的endpoint---这将是一个完美的解决方法.如果你想看这个API,请查看Demo,它有两个target:一个是Demo(使用Moya的基本形式),一个是DemoMultiTarget(使用编辑版的MutiTarget形式)

Multiple targets when using associatedtype(在Mutiple target中使用关联类型)

当调用一个网络请求时,Moya可以让你静态的验证参数。你有可能想扩展Moya的TargetType来验证自定义的类型。其中一种情况如在request请求中基于各种请求返回各种序列化对象,而不是直接返回MoyaResponse。这种需求可以通过向TargetType中添加associatetype来完成。

protocol DecodableTargetType: Moya.TargetType {
    associatedType ResultType: SomeJSONDecodableProtocolConformance
}

enum UserApi: DecodableTargetType {
    case get(id: Int)
    case update(id: Int, name: String)
    ...

    var baseURL: URL { ... }
    var path: String { switch self ... }
    var method: Moya.Method { ... }

    typealias ResultType = UserModel
}

因为associatedtype,所以MultiTarget不能被当做DecodableTargetType类型(ps:因为它MultiTarget源码实现没有实现这个扩展协议)。所以我们需要使用MultiMoyaProvider的变体。它不需要一个泛型参数(经过查看相关issue话题,这个作者考虑后的设计,推荐强类型)。因此,请求可以被调用并且任何遵循TargetType协议的实例对象都可以作为参数。使用MultiMoyaProvider允许你使用关联类型来编写及包装请求

例如,我们可以创建一个requestDecoded方法并返回ResultType而不是直接返回MoyaResponse。

extension MultiMoyaProvider {
    func requestDecoded<T: DecodableTargetType>(_ target: T, completion: @escaping (_ result: Result<[T.ResultType], Moya.Error>) -> ()) -> Cancellable {
        return request(target) { result in
            switch result {
            case .success(let response):
                if let parsed = T.ResultType.parse(try! response.mapJSON()) {
                    completion(.success(parsed))
                } else {
                    completion(.failure(.jsonMapping(response)))
                }
            case .failure(let error):
                completion(.failure(error))
            }
        }
    }
}

这个代码的优美之处在于,它的回调中的输入类型隐式的由传入的target类型决定

你可以传递任何DecodableTargetType来启动请求

let provider = MultiMoyaProvider()
provider.requestDecoded(UserApi.get(id: 1)) { result in
    switch result {
    case .success(let user):
      // type of `user` is implicitly `UserModel`. Using any other type results
      // in compile error
      print(user.name)
    }
}

当使用关联类型时,你将不得不为各种的target定义各种不同的类型。比如,我们有一另外一个target--SessionApi

struct SessionApi: DecodableTargetType {
    typealias ResultType = SessionModel
}

它有不同的ResultType。但我们可以使用MultiMoyaProvider的同一个实例对象:

provider.requestDecoded(SessionApi.get) { result in
    switch result {
    case .success(let session):
        // type of `user` is implicitly `SessionModel` here
    }
}

总结 这小节的核心:

  1. 当TargetType的实现里面的API太多了,需要分割成多个独立的TargetType,而常规使用MoyaProvider来创建请求就会变得庞大了。所以MutiTarget乘时而生。
  2. MutiTarget的使用
  3. 在MutiTarget中如何使用关联类型。(关键是扩展MultiMoyaProvider,例如一个返回结果的模型序列化的实现)

ps: 没有找到MultiMoyaProvider,自己推断它就是MoyaProvider??
经过搜索Moya github issue 找到个 [WIP] MoyaProvider variant without generic parameter #910
对于实现为 class MultiMoyaProvider: MoyaProvider<MultiTarget> { }

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

推荐阅读更多精彩内容

  • 文章摘自Moya官方文档 Targets Moya的使用始于定义一个target——典型的是定义一个符合Targe...
    Jt_Self阅读 16,180评论 0 27
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,735评论 18 139
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,538评论 0 4
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,019评论 6 13
  • 用非语言指令和孩子交流,有意想不到的效果。非语言指令包括:暗号、手势、物品、表情……这样不但可以减少日常...
    北京时间管理学院阅读 963评论 0 0