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之外其他参数都有默认值。
- URLConvertible
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的方法。通过扩展让String
、URL
、URLComponents
都实现了该协议,也就是我们传进来的url只要是这三种类型的都可以。
extension String: URLConvertible {
...
extension URL: URLConvertible {
...
extension URLComponents: URLConvertible {
...
- HTTPMethod
HTTPMethod就是一个定义请求方法的枚举类。
- Parameters
Parameters就是字典类型的别名:
public typealias Parameters = [String: Any]
typealias
用来定义别名
- ParameterEncoding
ParameterEncoding也是一个协议,它的作用相当于AFNetwork的AFURLRequestSerialization。有两个结构体实现了该协议:URLEncoding
、JSONEncoding
。这里默认值是URLEncoding.default
。
- HTTPHeaders
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
RequestInterceptor请求拦截器,有点像OkHttp的东西,后面再看有什么用。
Session
AF的request方法实际调用了Session.default
的request方法。
public static let `default` = Session()
default
是Session
的一个单例。这里default用单引号包围起来是因为default是Swift的关键字,所以不能直接用来命名。
Session有一个初始化方法加了一个convenience
字段。
在Swift中类的实例在初始化的时候必须给所有成员变量都赋上初始值,Swift提供了两种初始化方式designated initializers
、convenience initializers
。
designated initializers是主要的初始化方法,类似Object-C里面的NS_DESIGNATED_INITIALIZER宏
。一般来说designated initializer只有一个,designated initializer负责调用父类的初始化方法,它要保证执行完后所有的属性都被赋值。
designated initializers
和convenience initializers
之间的规则:
- 1、designated initializer必须调用父类的designated initializer;
- 2、convenience initializer必须调用本类的其他初始化方法;
- 3、convenience initializer最终必须调用到designated initializer
类的初始化方法在调父类的初始化方法之前,必须初始化完自己所有的成员变量。相反,如果是调用自己的其他初始化方法,则必须在调用完成后再初始化自己的成员变量。
看看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
}
- 1、首先在初始化的过程中给
rootQueue
设置了默认值
rootQueue: DispatchQueue = DispatchQueue(label: "org.alamofire.session.rootQueue")
rootQueue用来处理所有内部回调和状态更新,它是串行队列。
- 2、设置
delegateQueue
也就是OperationQueue
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.
- 3、
requestQueue
和serializationQueue
都把target设置成了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继承优先级。
- .main as target for UI work
- .global as target for other work that needs to be done as soon as possible
- nil as target for work that just needs to get done at some point (your not bothered when)
另外串行队列的任务是不会和它所属的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是一个协议,有两个结构体实现了该协议URLEncoding
、JSONEncoding
。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提供了map
和flatmap
方法,可以不用解包就可以执行相应的操作。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 {
private let lock = UnfairLock()
......
@discardableResult
func write(_ 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) -> Void) -> Self {
return response(queue: queue,
responseSerializer: JSONResponseSerializer(options: options),
completionHandler: completionHandler)
}
@discardableResult
public func response(
queue: DispatchQueue = .main,
responseSerializer: Serializer,
completionHandler: @escaping (DataResponse) -> 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 == .finished
和mutableState.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) -> 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) -> 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) -> 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)
}
}
}
如果有一个出错则直接退出。
- NSOperation 高级用法之NSOperation基础(NSOperation源码分析)(上)
- target parameter in DispatchQueue
- Swift4 中访问控制 private和fileprivate的区别