Request
属于中间管理类、基类,用于链接上层管理类SessionManager
及下层功能细分子类DataRequest
、DownloadRequest
、UploadRequest
、StreamRequest
,提供了一些基类方法的定义和实现
参数编码 URLEncoding
-
.get
,.head
,.delete
: 对参数key和value分别百分号编码,以key=value
的形式用&
符号连接,最后拼接到url的后面,作为request的url -
.post
:对参数key和value分别百分号编码,以key=value
的形式用&
符号连接,以UTF-8编码后作为request的httpbody
DataRequest
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() }
初始化DataRequest
,绑定到delegate
,request.resume()
会执行到task.resume()
,开始执行任务。而基类的初始化方法,会根据传入的RequestTask
类型,生成不同的taskDelegate
。
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
}
把request
以下标的方式绑定到delegate
,在代理方法中就可以方便的取出request.delegate
,调用具体功能实现的代码,从而实现功能分离,具体代理任务实现的下发。这里之所以用task
作为下标,是因为在代理方法中,task
最容易取到。
代理任务下发的两种情况:
- 用户提供方案,否则系统默认
- 用户可以监听,同时实现必要任务
适配器RequestAdapter
RequestAdapter
可以用于请求从定向,也可以对request
做处理
class TAdapter: RequestAdapter {
func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
var req = urlRequest
req.setValue("tokenValue", forHTTPHeaderField: "token")
return req
}
}
开始请求:
SessionManager.default.adapter = TAdapter()
SessionManager.default.request(url, parameters: param)
.response { (response) in
}
如下headers里面可以看到
RequestRetrier
RequestRetrier
重试请求
class TRetry: RequestRetrier {
func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
completion(true, 1)//重试,延迟1秒
}
}
开始请求:
如果请求失败CompleteWithError
不为空,则会执行协议方法,重试请求
SessionManager.default.retrier = TRetry()
SessionManager.default.request(url, parameters: param)
.response { (response) in
}.validate { (request, res, data) -> Request.ValidationResult in
return .failure(NSError(domain: "333", code: 111, userInfo: nil))
OperationQueue
TaskDelegate
作为具体任务实现代理类,持有任务队列:public let queue: OperationQueue
,初始化可以看出queue要求同时只能运行一个任务,相当于串行运行
self.queue = {
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 1
operationQueue.isSuspended = true
operationQueue.qualityOfService = .utility
return operationQueue
}()
通过queue.addOperation
把任务添加到队列中,设置queue.isSuspended
保证异步请求完成后继续执行queue
里的任务,从而控制请求开始闭包,及数据解析闭包的执行顺序