Alamofire源碼學習目錄合集linux
SessionDelegate.swift
EventMonitor.swift
NetworkReachabilityManager.swiftswift
//根據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
}
複製代碼
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?)
}
複製代碼
// 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, 用來保存Request對象與URLSessionTask的雙向映射, 該結構體被Session持有,能夠用來快速根據Request找到對應的URLSessionTask, 或者根據URLSessionTask找到對應的Request。api
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
}
}
}
複製代碼
/// 內部代理, 對應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>)
}
複製代碼
func performEvent(_ event: @escaping (EventMonitor) -> Void) {
//在本身的隊列中,異步循環, 在每一個監聽器各自的隊列回調方法
queue.async {
for monitor in self.monitors {
monitor.queue.async { event(monitor) }
}
}
}
複製代碼
public typealias Listener = (NetworkReachabilityStatus) -> Void
純屬我的理解, 可能存在理解錯誤的地方, 若有錯誤, 歡迎評論指出~ 感謝~數組