Alamofire源码学习(三): Session相关的其余几个类

往期导航:

Alamofire源码学习目录合集linux

相关文件:

SessionDelegate.swift
EventMonitor.swift
NetworkReachabilityManager.swiftswift

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。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
        }
    }
}
复制代码

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。

纯属我的理解, 可能存在理解错误的地方, 若有错误, 欢迎评论指出~ 感谢~数组

相关文章
相关标签/搜索