如今Alamofire
可以说是Swift
工程必备框架了。
本篇开始研究学习相关知识(Alamofire 5.4.4
版本)。先看下工程总览:
从框架的代码结构来看,这里的内容应该不少。我们将目标分解,先研究其工作流程,认识下相关类,为后面的深入做准备。
巧用 Test case
建议打开工程后,先翻一遍Tests
文件夹,然后跑一遍所有的Tests
,会有惊喜。别问我怎么知道的,都是泪啊。
注意:在这之前,你需要做两件重要的事:
- 修改
Tests
文件夹下TestHelpers.swift
中第50
行的httpbin.org
替换为www.httpbin.org
- 还是这个文件的第
220
行的Host.localhost
替换为Host.httpBin
这保证了你能连接到正确的http
测试服务器。
好了,下面是我跑出的测试结果:
在这里会有各种各样的使用案例,敬请翱翔吧!
工作流程
本节,我们分析一个testRequestResponse
测试用例,理清整个请求流程。这也是本篇的主要目标。
可以看到,在除去 Test 相关代码,核心就只有一句了:
1 |
|
这里主要做了两件事:
- 创建
Request
- 使用
Request
发起请求
同时引出了我们需要了解的几个类:
AF - Session 类的全局实例对象
Session
是URLSession
的封装。主要负责创建并管理Request
。同时它也负责请求队列/拦截/认证/重定向以及缓冲的管理。
Request & DataRequest
AF.request(url, parameters: ["foo": "bar"])
就是创建了一个DataRequest
。而DataRequest
继承于Request
。
Request
封装了一个请求信息,大致包含:请求状态,进度,事件回调等。
DataRequest
基于Request
增加了接收数据的功能,通过mutableData
将收到的数据存储在内存中。
DataResponse
DataResponse
封装了相应相关信息。它是一个泛型结构体,定义了两个泛型Success
、Failure
分别代表请求成功和失败对于的数据类型。
对于测试用例的响应类型 AFDataResponse<Data?>
是一个类型别名:
1 |
|
它使用 AFError
作为默认的错误类型。
连起来,串一串
好了,大致了解了相关数据类型。这里我们尝试把整体流程串起来。
首先是创建Request
的流程。
需要说明的是Request
分为以下几种类型:
DataRequest
DataStreamRequest
DownloadRequest
UploadRequest
其中DataRequest
最为常用,其次就是上传下载了。DataStreamRequest
表示还没接触过。。。
这几种Request
都有对应的创建方法。(方法签名太长,就不贴了。)他们大多都有相同参数:
- convertible - 请求对应的 URL
- method - 请求方法
- parameters - 请求参数
- encoding(或 encoder) - 负责将参数编码进请求中
- headers - 额外的请求头信息
- interceptor - 拦截器,这个后面具体讲
- requestModifier - 请求修改器,可以进一步修改 Request
在收集的各种参数后,会封装到RequestConvertible
或RequestEncodableConvertible
中,这两个结构体都遵循了URLRequestConvertible
协议,可以生成URLRequest
。简单看下它们的实现:
1 |
|
1 |
|
对比两份实现,只有关于编码方面的细微差别,这里先留个问号,可能必须深入到内部才能了解到这样设计的初衷。
其次是配置阶段。
创建好的Request
会通过 func perform(_ request: Request)
方法进行分发,根据不同类型的Request
执行不同的配置方法:
1 |
|
各版本的配置方法最终又会落脚到这里:
1 |
|
下面是最后的配置:
1 |
|
可以看到这里主要创建 task。最后是对 task 的配置。(这次真的是最后一次配置了 😂):
1 |
|
这里主要是同步Request
的状态到task
。
终于到这里创建一个 Request 的流程走完了!🤣
下一步是resume
这个请求。request.response { resp in xxx }
这里的response
方法定义在ResponseSerialization.swift
文件DataRequest
的一个扩展中:
1 |
|
response
方法的变体有多种,分别用于请求不同的数据类型:
- 将请求数据解析为
String
的responseString
- 将请求数据解析为
JSON
的responseJSON
- 将请求数据解析为模型的
responseDecodable
- 。。。
这些不同的版本本质上是使用appendResponseSerializer(_:)
方法添加了不同的解析器。
1 |
|
总结
好了,今天我们大致熟悉了 Alamofire 的请求流程,明白的一个请求从创建到发起是如何进行的。后续我会顺着这个思路,逐步分析该流程种的细节部分。敬请期待。感谢大家的阅读!