【Kickstarter-iOS 源码分析】05 - 网络请求的处理和 Deep Linking

Kickstarter-iOS源码地址 >>

网络请求的处理

Environment 中,可以了解到 Service 是处理应用中所有网络请求的。进入到 Service, 这里编写了所有的网络请求方法。再仔细看,你会发现很多请求是通过类似 request(.facebookConnect(facebookAccessToken: token)) 去调用的。我们就先来看看这个 request() 方法的参数 Route

Route

Route 的部分代码如下:

internal enum Route {
  case activities(categories: [Activity.Category], count: Int?)
  case addImage(fileUrl: URL, toDraft: UpdateDraft)
  case addVideo(fileUrl: URL, toDraft: UpdateDraft)
  case backing(projectId: Int, backerId: Int)
  // ...

  internal var requestProperties:
    (method: Method, path: String, query: [String: Any], file: (name: UploadParam, url: URL)?) {

    switch self {
    case let .activities(categories, count):
      var params: [String: Any] = ["categories": categories.map { $0.rawValue }]
      params["count"] = count
      return (.GET, "/v1/activities", params, nil)

    case let .addImage(file, draft):
      return (.POST, "/v1/projects/\(draft.update.projectId)/updates/draft/images", [:], (.image, file))

    case let .addVideo(file, draft):
      return (.POST, "/v1/projects/\(draft.update.projectId)/updates/draft/video", [:], (.video, file))

    case let .backing(projectId, backerId):
      return (.GET, "/v1/projects/\(projectId)/backers/\(backerId)", [:], nil)

     // ...
    }
  }
}

如果你打开源文件,你会发现,Route枚举编写了所有用到的请求,并且定义了 requestProperties 属性,这样我们就可以通过类似 .facebookConnect(facebookAccessToken: token)去获取到想要的请求,然后通过 requestProperties 属性,获取到请求参数,接着做进一步的网络请求。

对于类似这种有多种可能情况的处理,用 enum 非常合适,而这也是开发过程中经常会遇到的。

既然各种请求都准备好了,下一步就要进行真正的网络请求了,这些代码就藏在 Service+RequestHelpers.swift

Service+RequestHelpers

这个文件暴露给外面的接口非常简单,如下:

extension Service {

  func fetch<A: Swift.Decodable>(query: NonEmptySet<Query>) -> SignalProducer<A, GraphError>

  func applyMutation<A: Swift.Decodable, B: GraphMutation>(mutation: B) -> SignalProducer<A, GraphError>

  func requestPagination<M: Argo.Decodable>(_ paginationUrl: String)
    -> SignalProducer<M, ErrorEnvelope> where M == M.DecodedType

  func request<M: Argo.Decodable>(_ route: Route)
    -> SignalProducer<M, ErrorEnvelope> where M == M.DecodedType

  func request<M: Argo.Decodable>(_ route: Route)
    -> SignalProducer<[M], ErrorEnvelope> where M == M.DecodedType

  func request<M: Argo.Decodable>(_ route: Route)
    -> SignalProducer<M?, ErrorEnvelope> where M == M.DecodedType
}

从这些方法的定义我们可以看到,全部使用了泛型,这就意味着一个方法就可以处理某一类型的请求。这六个方法就可以处理整个应用的请求,是不是觉得非常强大😁?

这也是值得我们学习的地方。所以在开发过程中,如果发现自己在重复写类似的代码,那么可以考虑使用泛型能不能解决问题。

Deep Linking

在开发中,我们通常需要通过 Universal Link、URL Scheme 和 Push Notification 等方式跳转到应用的某一个页面。我们来看一下 Kickstarter-iOS 是怎么处理的。

打开 Navigation.swift ,跟网络请求一样,也是用 enum 定义了所有用户去往的目标页面。

那在 Kickstarter-iOS 中,它是怎样通过 deep linking 传入的 url 来最终得到 Navigation 其中的一个 case,然后跳转到目标页面呢?

首先,它用一个字典 allRoutes: [String: (RouteParams) -> Decoded<Navigation>] 保存了所有的 routes:其中 key 是 url 的模板;value 是一个闭包,这个闭包是根据url 携带的参数解析成 Navigation

然后用一个 match() 方法,把传入的 url,最终解析成Navigation 这里面最关键的一个方法是 parsedParams() ,大家可以去仔细看一下怎么实现的。

extension Navigation {
  public static func match(_ url: URL) -> Navigation? {
    return allRoutes.reduce(nil) { accum, templateAndRoute in
      let (template, route) = templateAndRoute
      return accum ?? parsedParams(url: url, fromTemplate: template).flatMap(route)?.value
    }
  }
}

想及时看到我的新文章的,可以关注我。同时也欢迎加入我管理的Swift开发群:536353151

下一篇文章:【Kickstarter-iOS 源码分析】06 - UI 的管理

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