Alamofire是iOS开发中非常著名的网络请求框架,github仓库地址为https://github.com/Alamofire/Alamofire。本篇文章主要是通过查看源码来观察其发起一个GET请求时的整个过程,并初步了解Alamofire的设计思想。
我们使用SessionManager发起一个GET请求
let url = "https://api.apiopen.top/getJoke"
let parameters = ["page":1, "count": 2, "type": "video"] as [String : Any]
SessionManager.default.request(url, method: .get, parameters: parameters)
.response { (response) in
}
SessionManager.default
public static let `default`: SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
return SessionManager(configuration: configuration)
}()
通过源码我们可以看到,default为SessionManager的一个单例,接着我们来查看SessionManager在初始化时所做的操作
public init(
configuration: URLSessionConfiguration = URLSessionConfiguration.default,
delegate: SessionDelegate = SessionDelegate(),
serverTrustPolicyManager: ServerTrustPolicyManager? = nil)
{
self.delegate = delegate
self.session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
commonInit(serverTrustPolicyManager: serverTrustPolicyManager)
}
private func commonInit(serverTrustPolicyManager: ServerTrustPolicyManager?) {
session.serverTrustPolicyManager = serverTrustPolicyManager
delegate.sessionManager = self
// 后台下载事件回传
delegate.sessionDidFinishEventsForBackgroundURLSession = { [weak self] session in
guard let strongSelf = self else { return }
DispatchQueue.main.async { strongSelf.backgroundCompletionHandler?() }
}
}
从上面可以看出
- 1
SessionManager
初始化的时候,初始化了SessionDelegate
对象,并将SessionManager
的delegate
指向SessionDelegate
. - 2 初始化
URLSession
,将URLSession
的代理指向SessionDelegate
- 3 将
SessionDelegate
的manager
指向SessionManager
,其中使用了weak
弱引用,避免两个对象的循环引用。
这里使用了代理转化的设计思想,用SessionDelegate遵守URLSessionDelegate.
SessionManager.default.request
@discardableResult
open func request(
_ url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil)
-> DataRequest
{
do {
let urlRequest = try URLRequest(url: url, method: method, headers: headers)
// 对.get, .head, .delete请求,把参数拼接到url中
let encodedURLRequest = try encoding.encode(urlRequest, with: parameters)
return request(encodedURLRequest)
} catch {
return request(failedWith: error)
}
}
open func request(_ urlRequest: URLRequestConvertible) -> DataRequest {
do {
let 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))
// 以URLSessionDataTask的identity做为key,DataRequest作为value存储起来
delegate[task] = request
if startRequestsImmediately { request.resume() }
return request
} catch {
return request(failedWith: error)
}
}
在调用request方法时我们可以看出来,首先,根据URLRequest的method对url进行编码。然后我们看下DadaRequest的初始化方法

在这里可以看出,初始化
DataRequest
,将 URLSession
指向 DataRequest
,初始化 DataTaskDelegate
,指向 DataTaskDelegate
的taskDelegate
然后
SessionDelegate
以URLSessionDataTask
的identity
做为key,DataRequest
作为value存储起来
最后 启动TaskDelegate
的queue
,调用task
的resume

请求值返回时,在SessionDelegate
中接受响应。
根据 dataTask
的identify
找到 DataTaskDelegate接收响应

最后将响应数据
data
存储在 TaskDelegate
的mutableData
中
Response

request()
方法返回的是DataRequest
对象,可以实现链式编程,在调用response
方法时在taskDelegate
中将data取出来,加到当前的queue中,串行执行,保证在请求有响应后,将data
回调出去。
以上就是Alamofire发起一个GET请求的过程,如有错误,望各位读者不吝赐教。
网友评论