Alamofire源码学习

2019-07-08  本文已影响0人  HoooChan

Alamofire最基本的使用方法:

AF.request("https://httpbin.org/get")

AF

AF其实是一个枚举类

Global namespace containing API for the default Session instance.

request方法的源码:

public static func request(_ url :       URLConvertible,
                           method :      HTTPMethod = .get,
                           parameters :  Parameters ? = nil,
                           encoding :    ParameterEncoding = URLEncoding.default,
                           headers :     HTTPHeaders ? = nil,
                           interceptor : RequestInterceptor ? = nil)->DataRequest {
    return Session.default.request(url,
                                   method: method,
                                   parameters: parameters,
                                   encoding: encoding,
                                   headers: headers,
                                   interceptor: interceptor)
}

先看传进来的参数,除了url之外其他参数都有默认值。

url的类型是URLConvertible,这其实是一个协议,类似于Java的抽象类:

public protocol URLConvertible {
    /// Returns a `URL` from the conforming instance or throws.
    ///
    /// - Returns: The `URL` created from the instance.
    /// - Throws:  Any error thrown while creating the `URL`.
    func asURL() throws -> URL
}

提供了一个返回URL的方法。通过扩展让StringURLURLComponents都实现了该协议,也就是我们传进来的url只要是这三种类型的都可以。

extension String: URLConvertible {
...
extension URL: URLConvertible {
...
extension URLComponents: URLConvertible {
...

HTTPMethod就是一个定义请求方法的枚举类。

Parameters就是字典类型的别名:

public typealias Parameters = [String: Any]

typealias用来定义别名

ParameterEncoding也是一个协议,它的作用相当于AFNetwork的AFURLRequestSerialization。有两个结构体实现了该协议:URLEncodingJSONEncoding。这里默认值是URLEncoding.default

HTTPHeaders是结构体:

public struct HTTPHeaders {
    private var headers: [HTTPHeader] = []
    ...

HTTPHeaders用一个数组保存headers,数组元素是HTTPHeader

更新headers的方法:

public mutating func update(_ header : HTTPHeader) {
    guard let index = headers.index(of: header.name) else {
        headers.append(header)
        return
    }

    headers.replaceSubrange(index ... index, with: [header])
}

先判断是否已经存在该header,如果没有则append新的,否则replaceSubrange进行替换。

headers.index(of: header.name)是扩展里面定义的方法:

extension Array where Element == HTTPHeader {
    /// Case-insensitively finds the index of an `HTTPHeader` with the provided name, if it exists.
    func index(of name: String) -> Int? {
        let lowercasedName = name.lowercased()
        return firstIndex { $0.name.lowercased() == lowercasedName }
    }
}

这种扩展只给元素为特定类型的Array增加方法。

RequestInterceptor请求拦截器,有点像OkHttp的东西,后面再看有什么用。

Session

AF的request方法实际调用了Session.default的request方法。

public static let `default` = Session()

defaultSession的一个单例。这里default用单引号包围起来是因为default是Swift的关键字,所以不能直接用来命名。

Session有一个初始化方法加了一个convenience字段。

在Swift中类的实例在初始化的时候必须给所有成员变量都赋上初始值,Swift提供了两种初始化方式designated initializersconvenience initializers

designated initializers是主要的初始化方法,类似Object-C里面的NS_DESIGNATED_INITIALIZER宏。一般来说designated initializer只有一个,designated initializer负责调用父类的初始化方法,它要保证执行完后所有的属性都被赋值。

designated initializersconvenience initializers之间的规则:

类的初始化方法在调父类的初始化方法之前,必须初始化完自己所有的成员变量。相反,如果是调用自己的其他初始化方法,则必须在调用完成后再初始化自己的成员变量。

看看Session的初始化方法:

public convenience init(configuration :            URLSessionConfiguration = URLSessionConfiguration.af.default,
                        delegate :                 SessionDelegate = SessionDelegate(),
                        rootQueue :                DispatchQueue = DispatchQueue(label: "org.alamofire.session.rootQueue"),
                        startRequestsImmediately : Bool = true,
                        requestQueue :             DispatchQueue ? = nil,
                        serializationQueue :       DispatchQueue ? = nil,
                        interceptor :              RequestInterceptor ? = nil,
                        serverTrustManager :       ServerTrustManager ? = nil,
                        redirectHandler :          RedirectHandler ? = nil,
                        cachedResponseHandler :    CachedResponseHandler ? = nil,
                        eventMonitors : [EventMonitor] = []) {
    let delegateQueue = OperationQueue(maxConcurrentOperationCount: 1, underlyingQueue: rootQueue, name: "org.alamofire.session.sessionDelegateQueue")
    let session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue)

    self.init(session: session,
              delegate: delegate,
              rootQueue: rootQueue,
              startRequestsImmediately: startRequestsImmediately,
              requestQueue: requestQueue,
              serializationQueue: serializationQueue,
              interceptor: interceptor,
              serverTrustManager: serverTrustManager,
              redirectHandler: redirectHandler,
              cachedResponseHandler: cachedResponseHandler,
              eventMonitors: eventMonitors)
}

    public init(session: URLSession,
                delegate: SessionDelegate,
                rootQueue: DispatchQueue,
                startRequestsImmediately: Bool = true,
                requestQueue: DispatchQueue? = nil,
                serializationQueue: DispatchQueue? = nil,
                interceptor: RequestInterceptor? = nil,
                serverTrustManager: ServerTrustManager? = nil,
                redirectHandler: RedirectHandler? = nil,
                cachedResponseHandler: CachedResponseHandler? = nil,
                eventMonitors: [EventMonitor] = []) {
        precondition(session.delegateQueue.underlyingQueue === rootQueue,
                     "Session(session:) intializer must be passed the DispatchQueue used as the delegateQueue's underlyingQueue as rootQueue.")

        self.session = session
        self.delegate = delegate
        self.rootQueue = rootQueue
        self.startRequestsImmediately = startRequestsImmediately
        self.requestQueue = requestQueue ?? DispatchQueue(label: "\(rootQueue.label).requestQueue", target: rootQueue)
        self.serializationQueue = serializationQueue ?? DispatchQueue(label: "\(rootQueue.label).serializationQueue", target: rootQueue)
        self.interceptor = interceptor
        self.serverTrustManager = serverTrustManager
        self.redirectHandler = redirectHandler
        self.cachedResponseHandler = cachedResponseHandler
        eventMonitor = CompositeEventMonitor(monitors: defaultEventMonitors + eventMonitors)
        delegate.eventMonitor = eventMonitor
        delegate.stateProvider = self
    }
rootQueue: DispatchQueue = DispatchQueue(label: "org.alamofire.session.rootQueue")

rootQueue用来处理所有内部回调和状态更新,它是串行队列。

let delegateQueue = OperationQueue(maxConcurrentOperationCount: 1, underlyingQueue: rootQueue, name: "org.alamofire.session.sessionDelegateQueue")

OperationQueue在Objective-C中就是NSOperationQueue,用来调度NSOperation的。maxConcurrentOperationCount用来控制可以同时执行的任务的数目,添加至OperationQueue对象中的所有的任务都是放到_underlyingQueue队列中执行的。这里underlyingQueue设置为了rootQueue,而且它们必须一样:
Session(session:) intializer must be passed the DispatchQueue used as the delegateQueue's underlyingQueue as rootQueue.

关于target queue苹果的文档有所描述:

"A dispatch queue's priority is inherited from its target queue. Use the dispatch_get_global_queue function to obtain a suitable target queue of the desired priority. If you submit a block to a serial queue, and the serial queue’s target queue is a different serial queue, that block is not invoked concurrently with blocks submitted to the target queue or to any other queue with that same target queue."

首先队列可以从target queue继承优先级。

另外串行队列的任务是不会和它所属的target queue中的任务并行处理的,也不会和任何其他与它有相同target queue的队列中的任务并行处理。这里requestQueue和serializationQueue的target queue都是rootQueue,也就保证了他们的任务都是串行处理的。

再看Session的request方法:

open func request(_ convertible : URLConvertible,
                  method :        HTTPMethod = .get,
                  parameters :    Parameters ? = nil,
                  encoding :      ParameterEncoding = URLEncoding.default,
                  headers :       HTTPHeaders ? = nil,
                  interceptor :   RequestInterceptor ? = nil)->DataRequest {
    let convertible = RequestConvertible(url: convertible,
                                         method: method,
                                         parameters: parameters,
                                         encoding: encoding,
                                         headers: headers)
    return request(convertible, interceptor: interceptor)
}

这里用外部传来的参数生成了一个RequestConvertible,它继承了URLRequestConvertible协议,该协议提供了一个生成URLRequesr的方法asURLRequest。

继续往下:

open func request(_ convertible : URLRequestConvertible, interceptor : RequestInterceptor ? = nil)->DataRequest {
    let request = DataRequest(convertible: convertible,
                              underlyingQueue: rootQueue,
                              serializationQueue: serializationQueue,
                              eventMonitor: eventMonitor,
                              interceptor: interceptor,
                              delegate: self)

    perform(request)

    return request
}

创建了DataRequest,并进行处理

func perform(_ request: DataRequest) {
    requestQueue.async {
        guard !request.isCancelled else { return }
        
        self.performSetupOperations(for: request, convertible: request.convertible)
    }
}

func performSetupOperations(for request: Request, convertible: URLRequestConvertible) {
    do {
        let initialRequest = try convertible.asURLRequest()
        rootQueue.async { request.didCreateURLRequest(initialRequest) }
            
        guard !request.isCancelled else { return }
            
        if let adapter = adapter(for: request) {
            ......
        } else {
            rootQueue.async { self.didCreateURLRequest(initialRequest, for: request) }
        }
    } catch {
        rootQueue.async { request.didFailToCreateURLRequest(with: error) }
    }
}

首先是调用URLRequestConvertible的asURLRequest方法创建URLRequest

看一下RequestConvertible的源码:

struct RequestConvertible : URLRequestConvertible {
    let url: URLConvertible
    let method: HTTPMethod
    let parameters: Parameters ?
    let encoding : ParameterEncoding
    let headers: HTTPHeaders ?

    func asURLRequest() throws->URLRequest {
        let request = try URLRequest(url : url, method : method, headers : headers)
            return try encoding.encode(request, with : parameters)
    }
}

它的asURLRequest方法还通过ParameterEncoding处理了请求参数的编码,做的就是AFNetwork的AFURLRequestSerialization一样的工作。

ParameterEncoding是一个协议,有两个结构体实现了该协议URLEncodingJSONEncoding。encoding默认是URLEncoding,来看看它的encode函数:

public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
    var urlRequest = try urlRequest.asURLRequest()
        
    guard let parameters = parameters else { return urlRequest }
        
    if let method = urlRequest.method, destination.encodesParametersInURL(for: method) {
        guard let url = urlRequest.url else {
            throw AFError.parameterEncodingFailed(reason: .missingURL)
        }
            
        if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty {
            let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters)
            urlComponents.percentEncodedQuery = percentEncodedQuery
            urlRequest.url = urlComponents.url
        }
    } else {
        if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
            urlRequest.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
        }
            
        urlRequest.httpBody = Data(query(parameters).utf8)
    }
    
    return urlRequest
}

Destination是一个枚举类,它定义了请求参数拼接的位置。有三种情况:根据请求方法决定、拼接在Url、设置在Body里面。destination的默认值是.methodDependent,也就是根据请求方法决定。

拼接到Url:

if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty {
    let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters)
    urlComponents.percentEncodedQuery = percentEncodedQuery
    urlRequest.url = urlComponents.url
}

urlComponents.percentEncodedQuery是可选类型,Swift的Optional提供了mapflatmap方法,可以不用解包就可以执行相应的操作。map和flatmap的区别在于map的闭包不能返回nil。

拼接参数:

private func query(_ parameters: [String: Any]) -> String {
    var components: [(String, String)] = []
        
    for key in parameters.keys.sorted(by: <) {
        let value = parameters[key]!
        components += queryComponents(fromKey: key, value: value)
    }
    return components.map { "\($0)=\($1)" }.joined(separator: "&")
}

创建完URLRequest之后,保存到DataRequest中:

func didCreateURLRequest(_ request : URLRequest) {
    protectedMutableState.write { $0.requests.append(request) }

    eventMonitor ? .request(self, didCreateURLRequest: request)
}

MutableState是在Request里面的定义的一个结构体,它保存了Request当前的状态、URLRequest和URLSessionTask等数据。protectedMutableState就是MutableState,只是用Protector包了一层来保证线程安全。Protector的源码:

final class Protector<T> {
    private let lock = UnfairLock()
    ......
    @discardableResult
    func write<U>(_ closure: (inout T) -> U) -> U {
        return lock.around { closure(&self.value) }
    }

Protector定义了一个锁,UnfairLock

final class UnfairLock {
    private let unfairLock: os_unfair_lock_t
    ......
    func around(_ closure: () -> Void) {
        lock(); defer { unlock() }
        return closure()
    }

around方法就是在执行这个闭包时先加锁,执行完成后解锁,defer内的代码在最后执行,也就是在return之前的时机。

Protector的write方法就是加锁之后,把自己的value通过引用传递给闭包对它的值进行修改。

现在adapter为空,先忽略,直接来到

rootQueue.async { self.didCreateURLRequest(initialRequest, for: request) }

func didCreateURLRequest(_ urlRequest: URLRequest, for request: Request) {
    guard !request.isCancelled else { return }
        
    let task = request.task(for: urlRequest, using: session)
    requestTaskMap[request] = task
    request.didCreateTask(task)
        
    updateStatesForTask(task, request: request)
}

调用request的task方法创建URLSessionTask,保存到requestTaskMap中,之后更新URLSessionTask的状态:

func updateStatesForTask(_ task : URLSessionTask, request : Request) {
    request.withState { (state)in
        switch (startRequestsImmediately, state) {
        case (true, .initialized):
            rootQueue.async { request.resume() }
        case (false, .initialized):
            // Do nothing.
            break
        case (_, .resumed):
            task.resume()
            rootQueue.async { request.didResumeTask(task) }
        case (_, .suspended):
            task.suspend()
            rootQueue.async { request.didSuspendTask(task) }
        case (_, .cancelled):
            task.cancel()
            rootQueue.async { request.didCancelTask(task) }
        case (_, .finished):
            // Do nothing
            break
        }
    }
}

获取request的state,同样是保证线程安全的:

func withState(perform : (State)->Void) {
    protectedMutableState.withState(perform: perform)
}

当state为.initialized并且startRequestsImmediately时,调用request.resume(),这时请求就开始了。

再回到Session初始化时

let session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue)

这里设置的delegate就是SessionDelegate

SessionDelegate在扩展里实现了这些协议:URLSessionDelegate、URLSessionTaskDelegate、URLSessionDataDelegate、URLSessionDownloadDelegate。

看一下URLSessionDataDelegate的didReceive data方法:

open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
    eventMonitor?.urlSession(session, dataTask: dataTask, didReceive: data)
        
    guard let request = stateProvider?.request(for: dataTask) as? DataRequest else {
        fatalError("dataTask received data for incorrect Request subclass: \(String(describing: stateProvider?.request(for: dataTask)))")
    }
    
    request.didReceive(data: data)
}

stateProvider是SessionDelegate的一个属性weak var stateProvider: SessionStateProvider?,SessionStateProvider是一个协议。Session在初始化时设置了delegate的stateProvider:

delegate.stateProvider = self

Session本身实现了这个协议:


extension Session: SessionStateProvider {
    func request(for task: URLSessionTask) -> Request? {
        return requestTaskMap[task]
    }

    func didGatherMetricsForTask(_ task: URLSessionTask) {
        requestTaskMap.disassociateIfNecessaryAfterGatheringMetricsForTask(task)
    }

    func didCompleteTask(_ task: URLSessionTask) {
        requestTaskMap.disassociateIfNecessaryAfterCompletingTask(task)
    }

    func credential(for task: URLSessionTask, in protectionSpace: URLProtectionSpace) -> URLCredential? {
        return requestTaskMap[task]?.credential ??
            session.configuration.urlCredentialStorage?.defaultCredential(for: protectionSpace)
    }

    func cancelRequestsForSessionInvalidation(with error: Error?) {
        requestTaskMap.requests.forEach { $0.finish(error: AFError.sessionInvalidated(error: error)) }
    }
}

所以最后就是在URLSession的回调中根据URLSessionDataTask来拿到DataRequest并做相应的处理。

request的didReceive方法

func didReceive(data: Data) {
    if self.data == nil {
        protectedData.directValue = data
    } else {
        protectedData.append(data)
    }
    
    updateDownloadProgress()
}

这里的Data也用Protector给包起来了,保证线程安全。

数据接收完成后,来到NSURLSessionTaskDelegate最重要的一个方法didCompleteWithError:

open func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    eventMonitor?.urlSession(session, task: task, didCompleteWithError: error)
        
    stateProvider?.request(for: task)?.didCompleteTask(task, with: error)
        
    stateProvider?.didCompleteTask(task)
}

func didCompleteTask(_ task : URLSessionTask, with error : Error ? ) {
    self.error = self.error ? ? error
    protectedValidators.directValue.forEach { $0() }

    eventMonitor ? .request(self, didCompleteTask: task, with: error)

    retryOrFinish(error: self.error)
}

func retryOrFinish(error: Error?) {
    guard let error = error, let delegate = delegate else {
        finish(); return
    }
    
    delegate.retryResult(for: self, dueTo: error) { retryResult in
        switch retryResult {
        case .doNotRetry, .doNotRetryWithError:
            self.finish(error: retryResult.error)
        case .retry, .retryWithDelay:
            delegate.retryRequest(self, withDelay: retryResult.delay)
        }
    }
}

如果error为空或者delegate为空就会直接跳到finish方法。

func finish(error: Error? = nil) {
    if let error = error { self.error = error }
        
    // Start response handlers
    processNextResponseSerializer()
    
    eventMonitor?.requestDidFinish(self)
}

这里就会对返回结果进行解析:

func processNextResponseSerializer() {
    guard let responseSerializer = nextResponseSerializer() else {
        ......
        
        return
    }
        
    serializationQueue.async { responseSerializer() }
}

通过nextResponseSerializer来获取responseSerializer,最后执行这个解析操作。responseSerializer是保存在 mutableState.responseSerializers中的。那它是什么时候保存进去的呢?

我们再调一个方法:

AF.request("https://httpbin.org/get")
    .responseJSON { response in
        if case let .success(value) = response.result {
            print(value)
        }
}

responseJSON是DataRequest的方法:

@discardableResult
public func responseJSON(queue: DispatchQueue = .main,
                         options: JSONSerialization.ReadingOptions = .allowFragments,
                         completionHandler: @escaping (DataResponse<Any>) -> Void) -> Self {
    return response(queue: queue,
                    responseSerializer: JSONResponseSerializer(options: options),
                    completionHandler: completionHandler)
}
@discardableResult
public func response<Serializer: DataResponseSerializerProtocol>(
    queue: DispatchQueue = .main,
    responseSerializer: Serializer,
    completionHandler: @escaping (DataResponse<Serializer.SerializedObject>) -> Void)
    -> Self
{
    appendResponseSerializer {
        // 数据解析的操作
        ......
    }
        
    return self
}

调用了appendResponseSerializer方法,传入一个闭包,这个闭包就是解析请求结果的函数。

func appendResponseSerializer(_ closure: @escaping () -> Void) {
    protectedMutableState.write { mutableState in
        mutableState.responseSerializers.append(closure)
            
        if mutableState.state == .finished {
            mutableState.error = AFError.responseSerializationFailed(reason: .responseSerializerAddedAfterRequestFinished)
        }
            
        if mutableState.responseSerializerProcessingFinished {
            underlyingQueue.async { self.processNextResponseSerializer() }
        }
    }
}

把这段代码改一下形式:

let tmpClosure : (inout MutableState) -> Void = { mutableState in
    mutableState.responseSerializers.append(closure)
    
    if mutableState.state == .finished {
        mutableState.error = AFError.responseSerializationFailed(reason: .responseSerializerAddedAfterRequestFinished)
    }
            
    if mutableState.responseSerializerProcessingFinished {
        self.underlyingQueue.async { self.processNextResponseSerializer() }
    }
}

protectedMutableState.write(tmpClosure)
// lock.around { tmpClosure(&self.value) }

就是加锁之后执行了tmpClosure,最终的结果就是以下代码执行:

mutableState.responseSerializers.append(closure)

if mutableState.state == .finished {
    mutableState.error = AFError.responseSerializationFailed(reason: .responseSerializerAddedAfterRequestFinished)
}

if mutableState.responseSerializerProcessingFinished {
    self.underlyingQueue.async { self.processNextResponseSerializer() }
}

也就是request的mutableState增加一个responseSerializer,把它保存在mutableState.responseSerializers

这里有两个关键的状态判断mutableState.state == .finishedmutableState.responseSerializerProcessingFinished

如果当前request的状态是finished,那就会设置一个responseSerializerAddedAfterRequestFinished错误。什么时候request的状态会变为finished呢?在processNextResponseSerializer函数中,对调用nextResponseSerializer方法去取responseSerializer,如果取不到就会进入以下方法:

var completions: [() -> Void] = []
            
protectedMutableState.write { mutableState in
    completions = mutableState.responseSerializerCompletions
                
    // Clear out all response serializers and response serializer completions in mutable state since the
    // request is complete. It's important to do this prior to calling the completion closures in case
    // the completions call back into the request triggering a re-processing of the response serializers.
    // An example of how this can happen is by calling cancel inside a response completion closure.
    mutableState.responseSerializers.removeAll()
    mutableState.responseSerializerCompletions.removeAll()
                
    if mutableState.state.canTransitionTo(.finished) {
        mutableState.state = .finished
    }
                
    mutableState.responseSerializerProcessingFinished = true
}
            
completions.forEach { $0() }
            
// Cleanup the request
cleanup()

这个时候就会设置request的state为.finished,同时responseSerializerProcessingFinished也会设置为true。

创建完URLRequest后可以做一些自定义的处理,也就是前面略过的adapter和Interceptor的作用。

func performSetupOperations(for request: Request, convertible: URLRequestConvertible) {
    do {
        let initialRequest = try convertible.asURLRequest()
        rootQueue.async { request.didCreateURLRequest(initialRequest) }
            
        guard !request.isCancelled else { return }
            
        if let adapter = adapter(for: request) {
            adapter.adapt(initialRequest, for: self) { result in
                do {
                    let adaptedRequest = try result.get()
                    
                    self.rootQueue.async {
                        request.didAdaptInitialRequest(initialRequest, to: adaptedRequest)
                        self.didCreateURLRequest(adaptedRequest, for: request)
                    }
                } catch {
                    let adaptError = AFError.requestAdaptationFailed(error: error)
                    self.rootQueue.async { request.didFailToAdaptURLRequest(initialRequest, withError: adaptError) }
                }
            }
        } else {
            rootQueue.async { self.didCreateURLRequest(initialRequest, for: request) }
            }
    } catch {
        rootQueue.async { request.didFailToCreateURLRequest(with: error) }
    }
}

调用adapter(for: request)来获取RequestAdapter。RequestAdapter是个协议,定义了一下方法:

func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (AFResult<URLRequest>) -> Void)

看看adapter(for request: Request)做了什么:

func adapter(for request: Request) -> RequestAdapter? {
    if let requestInterceptor = request.interceptor, let sessionInterceptor = interceptor {
        return Interceptor(adapters: [requestInterceptor, sessionInterceptor])
    } else {
        return request.interceptor ?? interceptor
    }
}

Interceptor -> RequestInterceptor -> RequestAdapter, RequestRetrier

如果request的interceptor和session的interceptor都不为空,则返回Interceptor,否则单独返回它们不为空的那个。

session的interceptor默认也是nil。

RequestInterceptor的adapt方法默认是什么都不做的:

public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (AFResult<URLRequest>) -> Void) {
    completion(.success(urlRequest))
}

这里@escaping用来定义逃逸闭包。因为这个闭包可能在函数执行完后才执行,比如以下情况:

public func escapingClosure (completion: @escaping () -> Void) {
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5000) {
        completion()
    }
}

如果我们把@escaping去掉会出现以下错误:
Closure use of non-escaping parameter 'completion' may allow it to escape

Interceptor是把requestInterceptor和sessionInterceptor保存起来,然后用递归调用RequestAdapter的adapter方法:

private func adapt(
    _ urlRequest: URLRequest,
    for session: Session,
    using adapters: [RequestAdapter],
    completion: @escaping (AFResult<URLRequest>) -> Void)
{
    var pendingAdapters = adapters
        
    guard !pendingAdapters.isEmpty else { completion(.success(urlRequest)); return }
        
    let adapter = pendingAdapters.removeFirst()
        
    adapter.adapt(urlRequest, for: session) { result in
        switch result {
        case .success(let urlRequest):
            self.adapt(urlRequest, for: session, using: pendingAdapters, completion: completion)
        case .failure:
            completion(result)
        }
    }
}

如果有一个出错则直接退出。

上一篇 下一篇

猜你喜欢

热点阅读