今天我们主要分析request底层原理,具体流程是什么?做了哪些工作?
1.Request源码
首先进行Request参数编码encode,使用URLEncoding,encode分别针对post、get请求进行了百分号编码,配置相关属性,调用query函数,最终将uirRequest作为函数返回值返回。
-
GET
query函数中,调用queryComponents函数进行一系列处理:递归查询拼接,百分号编码,元组、拼接为“$0= 1 ” 再 加 “ 1”再加“ 1”再加“”符号的格式。
注: .map函数:表示对集合中所有元素进行映射操作。
.joined函数:使用指定字符拼接集合中的所有元素。 -
POST
POST请求多了个HTTPHeaderField的设置“Content-type”,拼接请求头。其它query流程同GET。
注意点:对于上传数组类型的数据,需要先将数据转化为JSON字符串。转换函数getJsonFromArray定义如下:
extension ViewController {
fileprivate func getJsonFromArray(_ array:Array<Any>) -> String{
let data = try? JSONSerialization.data(withJSONObject: array, options: .prettyPrinted)
return String(data: data!, encoding: .utf8) ?? ""
}
}
2.调用带参数request函数
- task
创建一个Requestable类型的结构体对象originalTask。DataRequest中Requestable为存储型的结构体。
该结构体中定义了一个属性urlRequest,定义了task函数进行同步queue.async。
问:为什么要设计Requestable结构体作为DataRequest与task之间的中间变量层来处理task?
因为本身DataRequest可以直接处理task,但是属于归属关系,耦合性高。所以使用DataRequest作为中间层,降低了二者之间的耦合性。
-
request
DataRequest,其初始化来自父类。采用工厂设计模式,根据传入的不同requestTask枚举类型,设置不同的参数
-
delegate[task] = request
task、request都已经准备好,然后进行绑定 -
startRequestsImmediately
最后执行startRequestsImmediately进行请求。
3.扩展
1. SessionDelegate与DataTaskDelegate的关系?
整体与局部关系:SessionDelegate针对SessionManager整体,DataTaskDelegate与其它构成了SessionDelegate与SessionTaskDelegate中的urlSession函数。
- strongSelf.taskDidComplete?(session, task, error) :给外边实现taskComplete代理方法的能力。
- strongSelf[task]?.delegate.urlSession :任务下发给TaskDelegate
2.为什么最后将queue.isSuspended置为false?
因为在每次的response中都会添加任务。
delegate.queue为TaskDelegate中定义的单例queue,并设置了isSuspend挂起状态。
设置queue.isSuspend = true,保证每当任务添加进队列,queue就被挂起,其它任何任务都无法执行,除非给出queue.isSuspend = false。所以这也是TaskDelegate最后要设置queue.isSuspend = false的原因。
通过上述分析,我们发现Alamofire的结构设计还是很清晰的,逻辑流程也十分简洁。只要我们坚定信念,拿下Alamofire不是问题。