往期导航:
相关文件:
SessionDelegate.swift
EventMonitor.swift
NetworkReachabilityManager.swift
SessionDelegate.swift
- 声明了类SessionDelegate, 实现URLSessionDelegate以及各个URLSessionTaskDelegate并把各个状态事件派发给事件监听器对象:
- 持有一个FileManager对象, 可使用自定义对象初始化, 用来处理下载请求的文件操作(删除已存在文件, 创建目录)
- 持有一个弱引用SessionStateProvider协议对象指向Session, 用来从Session保存的Request-Task的映射关系中, 根据Task获取对应的Request对象
- 持有一个强引用EventMonitor协议对象, 用来接收请求中的各个状态事件
- 只有一个方法:
//根据Task获取对应的Request, 并转换成对应的子类 func request<R: Request>(for task: URLSessionTask, as type: R.Type) -> R? { guard let provider = stateProvider else { assertionFailure("StateProvider is nil.") return nil } //从SessionStateProvider(Session)中根据task获取request return provider.request(for: task) as? R }
- 定义协议SessionStateProvider, 连接Session跟SessionDelegate(Sesson实现了该协议)
protocol SessionStateProvider: AnyObject { //从Session中获取证书管理器、重定向管理器、缓存管理器 var serverTrustManager: ServerTrustManager? { get } var redirectHandler: RedirectHandler? { get } var cachedResponseHandler: CachedResponseHandler? { get } //从Session的RequestTaskMap映射中根据task拿request func request(for task: URLSessionTask) -> Request? //获取到任务任务指标后的回调 func didGatherMetricsForTask(_ task: URLSessionTask) //请求完成的回调, 后续可能会继续去获取任务指标 func didCompleteTask(_ task: URLSessionTask, completion: @escaping () -> Void) //认证授权处理 func credential(for task: URLSessionTask, in protectionSpace: URLProtectionSpace) -> URLCredential? //Session失效的回调 func cancelRequestsForSessionInvalidation(with error: Error?) } - 四次扩展类SessionDelegate实现对应实现四个URLSessionDelegate及URLSessionTaskDelegate协议, 用来处理Session以及URLSessionTask变化
// MARK: URLSessionDelegate extension SessionDelegate: URLSessionDelegate { open func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { //Session不可用时, 通知监听器, 然后回调Session取消全部请求 eventMonitor?.urlSession(session, didBecomeInvalidWithError: error) stateProvider?.cancelRequestsForSessionInvalidation(with: error) } } // MARK: URLSessionTaskDelegate extension SessionDelegate: URLSessionTaskDelegate { //定义元组包裹认证处理方式, 证书, 以及错误 typealias ChallengeEvaluation = (disposition: URLSession.AuthChallengeDisposition, credential: URLCredential?, error: AFError?) //收到需要验证证书的回调 open func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { //告知事件监听器 eventMonitor?.urlSession(session, task: task, didReceive: challenge) let evaluation: ChallengeEvaluation //组装认证方式, 证书, 错误信息 switch challenge.protectionSpace.authenticationMethod { case NSURLAuthenticationMethodServerTrust: //HTTPS认证 evaluation = attemptServerTrustAuthentication(with: challenge) case NSURLAuthenticationMethodHTTPBasic, NSURLAuthenticationMethodHTTPDigest, NSURLAuthenticationMethodNTLM, NSURLAuthenticationMethodNegotiate, NSURLAuthenticationMethodClientCertificate: //其他认证方式 evaluation = attemptCredentialAuthentication(for: challenge, belongingTo: task) default: evaluation = (.performDefaultHandling, nil, nil) } //获取证书失败的话, 该请求失败, 传递错误 if let error = evaluation.error { stateProvider?.request(for: task)?.didFailTask(task, earlyWithError: error) } //结果回调 completionHandler(evaluation.disposition, evaluation.credential) } //处理服务器认证 func attemptServerTrustAuthentication(with challenge: URLAuthenticationChallenge) -> ChallengeEvaluation { let host = challenge.protectionSpace.host guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, let trust = challenge.protectionSpace.serverTrust else { //如果没有自定义证书管理器 直接返回默认处理即可 return (.performDefaultHandling, nil, nil) } do { guard let evaluator = try stateProvider?.serverTrustManager?.serverTrustEvaluator(forHost: host) else { return (.performDefaultHandling, nil, nil) } //从ServerTrustManager中取ServerTrustEvaluating对象, 执行自定义认证 try evaluator.evaluate(trust, forHost: host) return (.useCredential, URLCredential(trust: trust), nil) } catch { //自定义认证出错的话, 返回取消认证操作 + 错误 return (.cancelAuthenticationChallenge, nil, error.asAFError(or: .serverTrustEvaluationFailed(reason: .customEvaluationFailed(error: error)))) } } //其他认证方式 func attemptCredentialAuthentication(for challenge: URLAuthenticationChallenge, belongingTo task: URLSessionTask) -> ChallengeEvaluation { guard challenge.previousFailureCount == 0 else { //如果之前认证失败了 直接跳过本次认证, 开始下一次认证 return (.rejectProtectionSpace, nil, nil) } guard let credential = stateProvider?.credential(for: task, in: challenge.protectionSpace) else { //没有获取到认证处理对象, 忽略本次认证 return (.performDefaultHandling, nil, nil) } return (.useCredential, credential, nil) } //上传进度 open func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { //通知监听器 eventMonitor?.urlSession(session, task: task, didSendBodyData: bytesSent, totalBytesSent: totalBytesSent, totalBytesExpectedToSend: totalBytesExpectedToSend) //拿到Request, 更新上传进度 stateProvider?.request(for: task)?.updateUploadProgress(totalBytesSent: totalBytesSent, totalBytesExpectedToSend: totalBytesExpectedToSend) } //上传请求准备上传新的body流 open func urlSession(_ session: URLSession, task: URLSessionTask, needNewBodyStream completionHandler: @escaping (InputStream?) -> Void) { //通知监听器 eventMonitor?.urlSession(session, taskNeedsNewBodyStream: task) guard let request = request(for: task, as: UploadRequest.self) else { //只有上传请求会响应这个方法 assertionFailure("needNewBodyStream did not find UploadRequest.") completionHandler(nil) return } //从request中拿到InputStream返回, 只有使用InputStream创建的上传请求才会返回正确, 否则会抛出错误 completionHandler(request.inputStream()) } //重定向 open func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { //通知监听器 eventMonitor?.urlSession(session, task: task, willPerformHTTPRedirection: response, newRequest: request) if let redirectHandler = stateProvider?.request(for: task)?.redirectHandler ?? stateProvider?.redirectHandler { //先看Request有没有自己的重定向处理器, 再看Session有没有全局重定向处理器, 有的话处理下 redirectHandler.task(task, willBeRedirectedTo: request, for: response, completion: completionHandler) } else { completionHandler(request) } } //获取请求指标 open func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { //通知监听器 eventMonitor?.urlSession(session, task: task, didFinishCollecting: metrics) //通知Request stateProvider?.request(for: task)?.didGatherMetrics(metrics) //通知Session stateProvider?.didGatherMetricsForTask(task) } //请求完成, 后续可能回去获取网页指标 open func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { //通知监听器 eventMonitor?.urlSession(session, task: task, didCompleteWithError: error) let request = stateProvider?.request(for: task) //通知Session请求完成 stateProvider?.didCompleteTask(task) { //回调内容为 确认请求指标完成后, 通知Request请求完成 request?.didCompleteTask(task, with: error.map { $0.asAFError(or: .sessionTaskFailed(error: $0)) }) } } //网络变更导致的请求等待处理 @available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) open func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) { eventMonitor?.urlSession(session, taskIsWaitingForConnectivity: task) } } // MARK: URLSessionDataDelegate extension SessionDelegate: URLSessionDataDelegate { //收到响应数据 open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { //通知监听器 eventMonitor?.urlSession(session, dataTask: dataTask, didReceive: data) //只有DataRequest跟DataStreamRequest会收到数据 if let request = request(for: dataTask, as: DataRequest.self) { request.didReceive(data: data) } else if let request = request(for: dataTask, as: DataStreamRequest.self) { request.didReceive(data: data) } else { assertionFailure("dataTask did not find DataRequest or DataStreamRequest in didReceive") return } } //处理是否保存缓存 open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @escaping (CachedURLResponse?) -> Void) { //通知监听器 eventMonitor?.urlSession(session, dataTask: dataTask, willCacheResponse: proposedResponse) if let handler = stateProvider?.request(for: dataTask)?.cachedResponseHandler ?? stateProvider?.cachedResponseHandler { //用request的缓存处理器处理缓存 handler.dataTask(dataTask, willCacheResponse: proposedResponse, completion: completionHandler) } else { //没有缓存处理器的话,采用默认逻辑处理缓存 completionHandler(proposedResponse) } } } // MARK: URLSessionDownloadDelegate extension SessionDelegate: URLSessionDownloadDelegate { //开始断点续传的回调 open func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) { //通知监听器 eventMonitor?.urlSession(session, downloadTask: downloadTask, didResumeAtOffset: fileOffset, expectedTotalBytes: expectedTotalBytes) guard let downloadRequest = request(for: downloadTask, as: DownloadRequest.self) else { //只有DownloadRequest能处理该协议 assertionFailure("downloadTask did not find DownloadRequest.") return } downloadRequest.updateDownloadProgress(bytesWritten: fileOffset, totalBytesExpectedToWrite: expectedTotalBytes) } //更新下载进度 open func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { //通知监听器 eventMonitor?.urlSession(session, downloadTask: downloadTask, didWriteData: bytesWritten, totalBytesWritten: totalBytesWritten, totalBytesExpectedToWrite: totalBytesExpectedToWrite) guard let downloadRequest = request(for: downloadTask, as: DownloadRequest.self) else { assertionFailure("downloadTask did not find DownloadRequest.") return } downloadRequest.updateDownloadProgress(bytesWritten: bytesWritten, totalBytesExpectedToWrite: totalBytesExpectedToWrite) } //下载完成 open func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { //通知监听器 eventMonitor?.urlSession(session, downloadTask: downloadTask, didFinishDownloadingTo: location) guard let request = request(for: downloadTask, as: DownloadRequest.self) else { assertionFailure("downloadTask did not find DownloadRequest.") return } //准备转存文件,定义(转存目录,下载options)元组 let (destination, options): (URL, DownloadRequest.Options) if let response = request.response { //从request拿到转存目录 (destination, options) = request.destination(location, response) } else { // If there's no response this is likely a local file download, so generate the temporary URL directly. (destination, options) = (DownloadRequest.defaultDestinationURL(location), []) } //通知监听器 eventMonitor?.request(request, didCreateDestinationURL: destination) do { //是否删除旧文件 if options.contains(.removePreviousFile), fileManager.fileExists(atPath: destination.path) { try fileManager.removeItem(at: destination) } //是否创建目录链 if options.contains(.createIntermediateDirectories) { let directory = destination.deletingLastPathComponent() try fileManager.createDirectory(at: directory, withIntermediateDirectories: true) } //转存文件 try fileManager.moveItem(at: location, to: destination) //回调给request request.didFinishDownloading(using: downloadTask, with: .success(destination)) } catch { //出错的话抛出异常 request.didFinishDownloading(using: downloadTask, with: .failure(.downloadedFileMoveFailed(error: error, source: location, destination: destination))) } } }
RequestTaskMap.swift
只定义了一个结构体:RequestTaskMap, 用来保存Request对象与URLSessionTask的双向映射, 该结构体被Session持有,可以用来快速根据Request找到对应的URLSessionTask, 或者根据URLSessionTask找到对应的Request。
struct RequestTaskMap {
//task的状态, 用来决定是否释放映射(task是否完成, task是否获取到请求指标)
private typealias Events = (completed: Bool, metricsGathered: Bool)
//task到request
private var tasksToRequests: [URLSessionTask: Request]
//request到task
private var requestsToTasks: [Request: URLSessionTask]
//task的状态
private var taskEvents: [URLSessionTask: Events]
//所有的request
var requests: [Request] {
Array(tasksToRequests.values)
}
//初始化 默认三个字典均为空
init(tasksToRequests: [URLSessionTask: Request] = [:],
requestsToTasks: [Request: URLSessionTask] = [:],
taskEvents: [URLSessionTask: (completed: Bool, metricsGathered: Bool)] = [:]) {
self.tasksToRequests = tasksToRequests
self.requestsToTasks = requestsToTasks
self.taskEvents = taskEvents
}
//角标存取task
subscript(_ request: Request) -> URLSessionTask? {
get { requestsToTasks[request] }
set {
guard let newValue = newValue else {
//如果新值为空, 表示删除映射, 检测下是否存在映射关系, 不存在就报错
guard let task = requestsToTasks[request] else {
fatalError("RequestTaskMap consistency error: no task corresponding to request found.")
}
requestsToTasks.removeValue(forKey: request)
tasksToRequests.removeValue(forKey: task)
taskEvents.removeValue(forKey: task)
return
}
//保存新的task
requestsToTasks[request] = newValue
tasksToRequests[newValue] = request
taskEvents[newValue] = (completed: false, metricsGathered: false)
}
}
//角标存取request
subscript(_ task: URLSessionTask) -> Request? {
get { tasksToRequests[task] }
set {
guard let newValue = newValue else {
guard let request = tasksToRequests[task] else {
fatalError("RequestTaskMap consistency error: no request corresponding to task found.")
}
tasksToRequests.removeValue(forKey: task)
requestsToTasks.removeValue(forKey: request)
taskEvents.removeValue(forKey: task)
return
}
tasksToRequests[task] = newValue
requestsToTasks[newValue] = task
taskEvents[task] = (completed: false, metricsGathered: false)
}
}
//映射个数, 做了两个字典个数判等
var count: Int {
precondition(tasksToRequests.count == requestsToTasks.count,
"RequestTaskMap.count invalid, requests.count: \(tasksToRequests.count) != tasks.count: \(requestsToTasks.count)")
return tasksToRequests.count
}
//task状态个数(映射个数, 而且这个属性没有用到)
var eventCount: Int {
precondition(taskEvents.count == count, "RequestTaskMap.eventCount invalid, count: \(count) != taskEvents.count: \(taskEvents.count)")
return taskEvents.count
}
//是否为空
var isEmpty: Bool {
precondition(tasksToRequests.isEmpty == requestsToTasks.isEmpty,
"RequestTaskMap.isEmpty invalid, requests.isEmpty: \(tasksToRequests.isEmpty) != tasks.isEmpty: \(requestsToTasks.isEmpty)")
return tasksToRequests.isEmpty
}
//task状态是否为空(其实就是isEmpty)
var isEventsEmpty: Bool {
precondition(taskEvents.isEmpty == isEmpty, "RequestTaskMap.isEventsEmpty invalid, isEmpty: \(isEmpty) != taskEvents.isEmpty: \(taskEvents.isEmpty)")
return taskEvents.isEmpty
}
//在Session收到task获取到请求指标完成后, 会来判断下task是否完全完成(请求完成,且获取指标完成),并更新taskEvents的状态 全部完成之后, 会删除映射关系, Session才会去执行请求完成的相关回调, 该方法返回的值为是否删除了映射关系
mutating func disassociateIfNecessaryAfterGatheringMetricsForTask(_ task: URLSessionTask) -> Bool {
guard let events = taskEvents[task] else {
fatalError("RequestTaskMap consistency error: no events corresponding to task found.")
}
switch (events.completed, events.metricsGathered) {
case (_, true): fatalError("RequestTaskMap consistency error: duplicate metricsGatheredForTask call.")
case (false, false): taskEvents[task] = (completed: false, metricsGathered: true); return false
case (true, false): self[task] = nil; return true
}
}
//在Session收到task的didComplete回调之后, 来判断下task是:1.直接完成,2.接着去获取请求指标. 并更新状态, 返回是否删除映射关系
mutating func disassociateIfNecessaryAfterCompletingTask(_ task: URLSessionTask) -> Bool {
guard let events = taskEvents[task] else {
fatalError("RequestTaskMap consistency error: no events corresponding to task found.")
}
switch (events.completed, events.metricsGathered) {
case (true, _): fatalError("RequestTaskMap consistency error: duplicate completionReceivedForTask call.")
#if os(Linux)
///Linux下请求不会获取指标, 所以完成之后可以直接删除映射
default: self[task] = nil; return true
#else
case (false, false):
if #available(macOS 10.12, iOS 10, watchOS 7, tvOS 10, *) {
taskEvents[task] = (completed: true, metricsGathered: false); return false
} else {
//watchOS 7以下也不会获取指标, 所以直接删除映射并返回true
self[task] = nil; return true
}
case (false, true):
self[task] = nil; return true
#endif
}
}
}
EventMonitor.swift
- 声明EventMonitor接口, 用来监听请求过程中的各种状态, 协议定义了一个回调监听器的队列(默认主队列), 以及一大堆方法。
- Alamofire中有三个类实现了该接口:
- AlamofireNotifications类, 用来在不同阶段发送通知使用
- CompositeEventMonitor类, 用来组合不同的监听器对象(下方详解)
- ClosureEventMonitor类, 持有N多个闭包, 把代理调用转换为闭包调用
- Alamofire中持有状况:
- SessionDelegate类持有一个CompositeEventMonitor组合监听器对象: Session在初始化时, 接受一个监听器数组作为初始化参数, 然后会把这些监听器加上AlamofireNotifications监听器组合成一个CompositeEventMonitor来教给SessionDelegate持有, 在Session的代理方法中, 回调这些监听器
- 每个Request对象也持有一个CompositeEventMonitor: 在Session中初始化Request对象时, 把SessionDelegate持有的组合模拟器传递给了创建的Request, 在Request响应状态时, 回调这些监听器
- 方法注解:
/// 内部代理, 对应URLSession的各个代理以及几个taskdelegate的代理, 还有几个专门针对Request及其子类的请求周期的代理方法 public protocol EventMonitor { /// 监听器回调队列, 默认主队列 var queue: DispatchQueue { get } // MARK: - URLSession事件及几个TaskDelegate相关事件 // MARK: URLSessionDelegate Events /// Event called during `URLSessionDelegate`'s `urlSession(_:didBecomeInvalidWithError:)` method. func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) // MARK: URLSessionTaskDelegate Events /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:didReceive:completionHandler:)` method. func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge) /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:)` method. func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:needNewBodyStream:)` method. func urlSession(_ session: URLSession, taskNeedsNewBodyStream task: URLSessionTask) /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)` method. func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest) /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:didFinishCollecting:)` method. func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:didCompleteWithError:)` method. func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:taskIsWaitingForConnectivity:)` method. @available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) // MARK: URLSessionDataDelegate Events /// Event called during `URLSessionDataDelegate`'s `urlSession(_:dataTask:didReceive:)` method. func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) /// Event called during `URLSessionDataDelegate`'s `urlSession(_:dataTask:willCacheResponse:completionHandler:)` method. func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse) // MARK: URLSessionDownloadDelegate Events /// Event called during `URLSessionDownloadDelegate`'s `urlSession(_:downloadTask:didResumeAtOffset:expectedTotalBytes:)` method. func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) /// Event called during `URLSessionDownloadDelegate`'s `urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:)` method. func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) /// Event called during `URLSessionDownloadDelegate`'s `urlSession(_:downloadTask:didFinishDownloadingTo:)` method. func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) // MARK: - Request 及其子类的相关请求周期事件 /// 原始URLRequest成功回调, 如果request有适配器,接下来会使用适配器处理原始URLRequest, 没有适配器的话,直接回调创建Request方法 func request(_ request: Request, didCreateInitialURLRequest urlRequest: URLRequest) /// 创建原始URLRequest失败回调 func request(_ request: Request, didFailToCreateURLRequestWithError error: AFError) /// 创建Request时,适配器对URLRequest成功处理后回调 func request(_ request: Request, didAdaptInitialRequest initialRequest: URLRequest, to adaptedRequest: URLRequest) /// 适配器处理Request失败 func request(_ request: Request, didFailToAdaptURLRequest initialRequest: URLRequest, withError error: AFError) /// 创建Request成功(在适配器处理后) func request(_ request: Request, didCreateURLRequest urlRequest: URLRequest) /// 创建URLSessionTask成功 func request(_ request: Request, didCreateTask task: URLSessionTask) /// 收到请求指标回调 func request(_ request: Request, didGatherMetrics metrics: URLSessionTaskMetrics) /// 由Alamofire创建抛出的错误, 比如自定义认证处理失败 func request(_ request: Request, didFailTask task: URLSessionTask, earlyWithError error: AFError) ///URLSessionTask请求完成,可能成功可能失败,接下来会判定是否需要重试,如果会重试,该回调会被调用多次 func request(_ request: Request, didCompleteTask task: URLSessionTask, with error: AFError?) /// 准备开始重试 func requestIsRetrying(_ request: Request) /// 请求完成,开始解析响应数据 func requestDidFinish(_ request: Request) //接下来的6个方法都为主动调用Request,然后影响到关联的Task时的回调,成对出现 /// Request调用resume方法的时候会回调该方法 func requestDidResume(_ request: Request) /// Request关联的URLSessionTask继续的时候回调 func request(_ request: Request, didResumeTask task: URLSessionTask) /// Request调用suspend挂起 func requestDidSuspend(_ request: Request) /// Request关联的Task被挂起 func request(_ request: Request, didSuspendTask task: URLSessionTask) /// Request调用cancel func requestDidCancel(_ request: Request) ///Request关联的Task被取消 func request(_ request: Request, didCancelTask task: URLSessionTask) // MARK: DataRequest 特有事件 /// 检测响应是否有效成功后回调 func request(_ request: DataRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, data: Data?, withResult result: Request.ValidationResult) /// DataRequest成功创建Data类型的DataResponse时回调(没有序列化) func request(_ request: DataRequest, didParseResponse response: DataResponse<Data?, AFError>) /// DataRequest成功创建序列化的DataResponse时回调 func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value, AFError>) // MARK: DataStreamRequest 特有事件 ///检测响应有效成功 func request(_ request: DataStreamRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, withResult result: Request.ValidationResult) /// 从stream中成功序列化数据后调用 func request<Value>(_ request: DataStreamRequest, didParseStream result: Result<Value, AFError>) // MARK: UploadRequest 特有事件 /// 上传请求成功创建Uploadable协议对象成功 func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) /// 上传请求创建Uploadable失败 func request(_ request: UploadRequest, didFailToCreateUploadableWithError error: AFError) /// 当上传请求从InputSteam开始提供数据时回调, 只有在上传请求的InputStream不是Data也不是文件url类型才会回调 func request(_ request: UploadRequest, didProvideInputStream stream: InputStream) // MARK: DownloadRequest 特有事件 /// 下载Task完成,且缓存文件被清除之后回调 func request(_ request: DownloadRequest, didFinishDownloadingUsing task: URLSessionTask, with result: Result<URL, AFError>) /// 下载请求成功创建转存目录后回调 func request(_ request: DownloadRequest, didCreateDestinationURL url: URL) /// 下载请求检测有效性成功 func request(_ request: DownloadRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, fileURL: URL?, withResult result: Request.ValidationResult) /// 使用原数据解析响应成功(没有序列化) func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse<URL?, AFError>) ///序列化解析响应成功 func request<Value>(_ request: DownloadRequest, didParseResponse response: DownloadResponse<Value, AFError>) } - 声明接口后, 扩展了接口, 对所有的方法添加了空实现, 对队列返回默认主队列。如果要自己实现监听器, 只用实现自己感兴趣的接口即可。
- CompositeEventMonitor组合监听器类:
- queue为一个异步队列//TODO
- 以监听器数组初始化, 持有这些数组
- 定义了一个performEvent方法用来派发回调
func performEvent(_ event: @escaping (EventMonitor) -> Void) { //在自己的队列中,异步循环, 在每个监听器各自的队列回调方法 queue.async { for monitor in self.monitors { monitor.queue.async { event(monitor) } } } } - ClosureEventMonitor闭包监听器类:
- queue为主队列
- 持有N个可选闭包,N为EventMonitor接口的方法数, 每个闭包对应一个接口, 闭包的出入参与接口的出入参对应
- 每个协议的实现都为调用对应的闭包
NetworkReachabilityManager.swift
- 网络状态监听管理器, watchos与linux不可用
- 核心为SystemConfiguration系统模块
- 定义网络状态枚举NetworkReachabilityStatus:
- 未知
- 无网络
- 联网(子状态ConnectionType):
- 以太网/wifi
- 移动网络
- 定义别名Listener,实际上是一个闭包:(话说swift不少第三方库都给闭包定义一个别名, 当做对象用, 函数是一等公民)
public typealias Listener = (NetworkReachabilityStatus) -> Void - 定义了几个快速判断网络的只读计算属性
- 持有一个reachabilityQueue的队列, 用来监听网络变化
- 定义了一个MutableState结构体, 持有一个Listener对象, 一个listener回调的队列, 一个旧的网络状态
- 持有一个线程安全的MutableState变量, 网络变化时,在listener回调队列中, 通知listener。
纯属个人理解, 可能存在理解错误的地方, 如有错误, 欢迎评论指出~ 感谢~