上次分析完了DataRequest层,接下来承接之前说的继续分析:
SessionManager.default //直接跳过Alamofire层调用也可以
.request(url, method: .get, parameters: parameters)
.response { (result) in
print(result)
}
open class SessionManager {
...
@discardableResult
open func request(
_ url: URLConvertible,
method: HTTPMethod = .get, /*默认为get方法*/
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil)
-> DataRequest
{
var originalRequest: URLRequest?
//创建URLRequest
do {
originalRequest = try URLRequest(url: url, method: method, headers: headers)
let encodedURLRequest = try encoding.encode(originalRequest!, with: parameters)
return request(encodedURLRequest)//轮到分析这里
} catch {
return request(originalRequest, failedWith: error)
}
}
...
}
- 之前分析到这一步:
request(encodedURLRequest)
,现在就来看看它:
open class SessionManager {
...
@discardableResult
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)
}
}
...
}
- 首先创建了一个结构体
Requestable
(Requestable
继承了TaskConvertible
协议),这个结构体变量名虽为originalTask
,但并不是URLSessionTask
,而是由它创建URLSessionTask
:
open class DataRequest: Request {
struct Requestable: TaskConvertible {
let urlRequest: URLRequest//结构体属性默认为初始化参数
func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
do {
let urlRequest = try self.urlRequest.adapt(using: adapter)
return queue.sync { session.dataTask(with: urlRequest) }
} catch {
throw AdaptError(error: error)
}
}
}
...
}
protocol TaskConvertible {
func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask
}
- 然后用
Requestable
和URLSessionTask
创建DataRequest
(DataRequest
继承了Request
),Request
初始化时,通过枚举任务类型创建对应任务代理进行下发任务:
open class DataRequest: Request {
...
}
open class Request {
...
init(session: URLSession, requestTask: RequestTask, error: Error? = nil) {
self.session = session
//分发任务
switch requestTask {
case .data(let originalTask, let task):
taskDelegate = DataTaskDelegate(task: task)
self.originalTask = originalTask
case .download(let originalTask, let task):
taskDelegate = DownloadTaskDelegate(task: task)
self.originalTask = originalTask
case .upload(let originalTask, let task):
taskDelegate = UploadTaskDelegate(task: task)
self.originalTask = originalTask
case .stream(let originalTask, let task):
taskDelegate = TaskDelegate(task: task)
self.originalTask = originalTask
}
delegate.error = error
delegate.queue.addOperation { self.endTime = CFAbsoluteTimeGetCurrent() }//记录时间
}
...
}
- 创建完
DataRequest
后,调用delegate[task] = request
(delegate
便是SessionManager
初始化时默认创建的SessionDelegate
),目的是为了使用时获取方便(通过重写下标引用进行绑定,可以降低耦合度):
open class SessionDelegate: NSObject {
...
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
}
}
...
}
- 下一步该是调用
request.resume()
启动任务了,最终便会调用task.resume()
,并发起通知:
open class Request {
...
open func resume() {
...
task.resume()
//通知启动
NotificationCenter.default.post(
name: Notification.Name.Task.DidResume,
object: self,
userInfo: [Notification.Key.Task: task]
)
}
...
}
task
启动后,先分析到这里。下一篇详细看看执行任务的TaskDelegate。
网友评论