一、动态适配adapter
-
RequestAdapter
协议 -
adapt
Alamofire
没有实现,需要自己实现
public protocol RequestAdapter {
func adapt(_ urlRequest: URLRequest) throws -> URLRequest
}
- 1: request 处理
- 2: request 重定向
SessionManager.default.adapter = DYZAdapter()
SessionManager.default.request(urlStr, method: .get, parameters: ["username":"dyz","password":"123"]).response { (response) in
debugPrint(response)
}
class DYZAdapter: RequestAdapter {
func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
// 1: request 处理
// var request = urlRequest
// request.setValue("Dyztoken", forHTTPHeaderField: "dyztoken")
// return request
// 2: request 重定向
let newUrlRequest = URLRequest.init(url: URL(string: "http://www.douban.com/j/app/radio/channels")!)
return newUrlRequest
}
}
- 实例1: 判断token,没有,先请求token,然后再请求,不浪费每一次请求
二、验证和重试
- validate 验证
SessionManager.default.request(myGetUrlString, method: .get, parameters: ["username":"dyz","password":"123"]).response { (response) in
debugPrint(response)
}.validate { (request, response, data) -> Request.ValidationResult in
guard let _ = data else {
return .failure(NSError.init(domain: "dyz", code: 10086, userInfo: nil))
}
let code = response.statusCode
if code == 404 {
return .failure(NSError.init(domain: "dyz", code: 10090, userInfo: nil))
}
return .success
}
- retrier
RequestRetrier
协议
public protocol RequestRetrier {
func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion)
}
SessionManager.default.retrier = DYZRetrier()
SessionManager.default.request(urlStr, method: .get, parameters: ["username":"dyz","password":"123"]).response { (response) in
debugPrint(response)
}.validate { (request, response, data) -> Request.ValidationResult in
guard let _ = data else {
return .failure(NSError.init(domain: "dyz", code: 10086, userInfo: nil))
}
let code = response.statusCode
if code == 404 {
return .failure(NSError.init(domain: "dyz", code: 10090, userInfo: nil))
}
return .success
}
class DYZRetrier: RequestRetrier {
func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
print("manager = \(manager)")
print("request = \(request)")
print("error = \(error)")
completion(true,1)
// 一定要有出口,不然持续递归就会发生很严重的影响
// completion(false,0)
}
}
三、TaskDelegate里的queue逻辑
-
startRequestsImmediately
默认值为true
SessionManager.default.startRequestsImmediately = false
-
operationQueue
初始化
init(task: URLSessionTask?) {
_task = task
self.queue = {
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 1
operationQueue.isSuspended = true
operationQueue.qualityOfService = .utility
return operationQueue
}()
}
- 请求完成
queue.isSuspended = false
@objc(URLSession:task:didCompleteWithError:)
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if let taskDidCompleteWithError = taskDidCompleteWithError {
taskDidCompleteWithError(session, task, error)
} else {
if let error = error {
if self.error == nil { self.error = error }
if
let downloadDelegate = self as? DownloadTaskDelegate,
let resumeData = (error as NSError).userInfo[NSURLSessionDownloadTaskResumeData] as? Data
{
downloadDelegate.resumeData = resumeData
}
}
queue.isSuspended = false
}
}
四、Timeline
requestStartTime
初始化请求的时间
initialResponseTime
从服务器接收或发送第一个字节的时间
requestCompletedTime
请求完成的时间
serializationCompletedTime
响应序列化完成的时间
latency
从请求开始到服务器的初始响应的时间间隔(以秒为单位)、TimeInterval 秒、secs 秒
requestDuration
从请求开始到请求完成的时间间隔(以秒为单位)
serializationDuration
从请求完成到响应序列化完成的时间间隔(以秒为单位)
totalDuration
从请求开始到完成响应序列化的时间间隔(以秒为单位)
五、Result
public enum Result<Value> {
case success(Value)
case failure(Error)
public var isSuccess: Bool { get }
public var isFailure: Bool { get }
public var value: Value? { get }
public var error: Error? { get }
}
枚举
网友评论