女儿惹她妈妈生气了,我让她去道歉。
“知错就改,快去找你妈,认错。”我催促她。
小家伙犹豫了半天,终于走进了厨房,对她妈说道:
“妈妈,请问你是周二珂吗?”
妻子很疑惑:“不是啊。”
“哦,对不起,我认错了。”
哈哈哈,意淫下。
最近看Alamifire
的源码,不得不说,好的源码的确让人获益良多。
但是看之前会很懵,如果不熟悉请求流程的话,很有可能坚持不下去,所以我这里简要的把他的一个请求流程简单分析一下,希望能够帮助到你。
Alamofire.request(posturl, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headerFile).responseJSON { (response) in
switch response.result{
case .success(_):
///成功
if let value = response.result.value {
}
case .failure(_):
///失败
print(response.result.error)
}
}
上面是一个请求json数据的一个标准用法,看源码可以发现Alamofire
提供了多个静态的请求方法,而这些请求方法全部是通过SessionManager
管理的。
由于Alamofire
本质上是对URLSession
的的一个封装,所以我们需要了解下URLSession
的结构,如上图一个session
管理者多个请求的task
和回调的delegate
。所以在SessionManager
中我们可以看到一个静态的default
常量,以及类型为SessionDelegate
的一个delegate
变量。
接下来我们分析上面的请求过程
首先Alamofire
将请求分成了几个大类
这里我就不一个个分析了,今天主要分析请求的流程。后面我会针对Alamofire
中几个比较怪的写法,我们不经常用的写法分析一下。
Alamofire.request
这个方法调用的是SessionManager
中的DataRequest的方法
open func request(_ urlRequest: URLRequestConvertible) -> DataRequest {
var originalRequest: URLRequest?
do {
originalRequest = try urlRequest.asURLRequest()
let originalTask = DataRequest.Requestable(urlRequest: originalRequest!)
let task = try originalTask.task(session: session, adapter: adapter, queue: queue)
let request = DataRequest(session: session, requestTask: .data(originalTask, task))
delegate[task] = request
if startRequestsImmediately { request.resume() }
return request
} catch {
return request(originalRequest, failedWith: error)
}
}
返回值还是DataRequest
,这是为了后面可以链式调用.responseJSON
。
这里的请求步骤简单来说是(这里还需要再研究下,回头会专门写个文章仔细分析下)
获取
urlRequest
获取
URLSessionTask
将
session
和URLSessionTask
封装至Request
相应的子类对象
这句delegate[task] = request
可能一开始看很难看懂,但其实这是给SessionDelegate
定义了下标方法,其实是通过SessionDelegate
的requests
属性来存储task
对应的request
的
///通过自身的requests属性来存储[task: request],用lock来确保线程安全。
/// Access the task delegate for the specified task in a thread-safe manner.
open subscript(task: URLSessionTask) -> Request? {
get {
lock.lock() ; defer { lock.unlock() }
return requests[task.taskIdentifier]
}
set {
lock.lock() ; defer { lock.unlock() }
requests[task.taskIdentifier] = newValue
}
}
后面的.responseJSON
这里是指定对返回的数据进行json
解析
public func responseJSON(
queue: DispatchQueue? = nil,
options: JSONSerialization.ReadingOptions = .allowFragments,
completionHandler: @escaping (DataResponse<Any>) -> Void)
-> Self
{
return response(
queue: queue,
responseSerializer: DataRequest.jsonResponseSerializer(options: options),
completionHandler: completionHandler
)
}
相信大家看到这里头肯定大了一圈,讲真的,我看到这里头大的一度想放弃。
[图片上传失败...(image-5840f4-1535621411864)]
但是头大了之后发现能思考更多东西了,这里我来一个一个分解开来
public func response<T: DataResponseSerializerProtocol>(
queue: DispatchQueue? = nil,
responseSerializer: T,
completionHandler: @escaping (DataResponse<T.SerializedObject>) -> Void)
-> Self
{
delegate.queue.addOperation {
let result = responseSerializer.serializeResponse(
self.request,
self.response,
self.delegate.data,
self.delegate.error
)
var dataResponse = DataResponse<T.SerializedObject>(
request: self.request,
response: self.response,
data: self.delegate.data,
result: result,
timeline: self.timeline
)
dataResponse.add(self.delegate.metrics)
(queue ?? DispatchQueue.main).async { completionHandler(dataResponse) }
}
return self
}
首先return
调用了DataRequest
的一个序列化结果的一个根方法,为什么说根方法呢,大家可以看下responseString
这个方法中也是return
这个方法,通过<T: DataResponseSerializerProtocol>
这个泛型参数就可以实现请求结果序列化成任意类型,只要遵守了DataResponseSerializerProtocol
这个协议,并实现即可。
而这个协议中的
serializeResponse
这个闭包则是起到传输数据然后返回序列化的结果的一个作用。
下面我阐述下代码调用的顺序。
调用
.responseJSON
————> 传入responseSerializer
这个参数(系列化的过程)来调用DataRequest的序列化根方法
-
DataRequest.jsonResponseSerializer(options: options)
这里就是序列化的方法,我尽量在注释中描述清楚public static func jsonResponseSerializer( options: JSONSerialization.ReadingOptions = .allowFragments) -> DataResponseSerializer<Any> { ///返回的是遵守DataResponseSerializerProtocol协议的一个结构体对象 ///这是一个初始化方法,初始化的对象存储了一个闭包。 return DataResponseSerializer { _, response, data, error in return Request.serializeResponseJSON(options: options, response: response, data: data, error: error) } ///所以上面可以等价为 let jsonResponseSerializer = DataResponseSerializer.init { (request, response, data, error) -> Result<Any> in ///这里就是根据闭包传过来的response, data, error来对结果进行序列化。 return Request.serializeResponseJSON(options: options, response: response, data: data, error: error) } return jsonResponseSerializer }
-
接下来看
DataRequest的序列化根方法
的实现,我们可以看到let result = responseSerializer.serializeResponse( self.request, self.response, self.delegate.data, self.delegate.error )
这里的responseSerializer.serializeResponse
传递参数然后调用第二步中序列化操作,最后得到return Request.serializeResponseJSON(options: options, response: response, data: data, error: error)
返回值
-
最后将得到的序列化结果
result
以及其他数据封装在dataResponse
中通过completionHandler
在指定线程中回调。var dataResponse = DataResponse<T.SerializedObject>( request: self.request, response: self.response, data: self.delegate.data, result: result, timeline: self.timeline )
这里对协议的关联类型以及属性的应用值得我们认真拜读一下
最终
最近很迷茫,来个人私信我陪我聊聊骚啊。
联系方式
- GitHub: 大猫传说中的gitHud地址
- 邮箱: 1030472953@qq.com