文章目录

  • Alamofire源码解析
  • 一、Alamofire目录结构
  • 二、使用的基本流程 (不讲解基本使用,从源码解析)
  • 1. 发起请求的源码 (举例:普通请求流程)
  • 2. SessionManager 的关键点解析
  • 3. SessionManager , 发起请求关键代码
  • 4. SessionDelegate , 收到请求关键代码
  • 5. TaskDelegate , 收到请求的关键代码
  • 5. 数据序列化的工作。 ResponseSerialization类,关键代码

  • 总结

Alamofire源码解析

解析版本: Alamofire V4.8.0

在使用Swift开发过程中,大家肯定都接触过这个网络请求框架,让我们的网络请求任务变得容易, 这个框架非常简单好用也易于封装,也会基于这个框架做一些自己的封装,比如加上自己的缓存方案等。

一、Alamofire目录结构

mac swift源码_swift


一共有17个类。 我会着重其中几个核心的地方,进行一个源码探索。

上面的17个类是什么意思呢,大概说下:

文件

作用

AFError

错误处理、错误合集、错误分类

Alamofire

对外的请求入口,请求、下载、上传、多文件上传

DispatchQueue+Alamofire

队列的扩展

MultipartFormData

多表单数据处理

NetworkReachabilityManager

网络环境监测工具

Notifications

通知名称列举

ParameterEncoding

URL、JSON、PropertyList Encoding编码处理

Request

定义请求类型,(普通,上传,多文件上传,下载)

Response

响应数据处理

ResponseSerialization

响应数据的序列化

Result

结果枚举类,请求结果的成功或者失败

ServerTrustPolicy

证书验证类,解决客户端与服务器的信任问题

SessionDelegate

处理Session的回调

SessionManager

创建各种请求(普通,上传,多文件上传,下载)

TaskDelegate

定义多重Delegate,处理URLSessionTask delegate回调

Timeline

负责请求中时间节点的处理

Validation

验证请求的方式 (比如根据返回的code,判定成功)

二、使用的基本流程 (不讲解基本使用,从源码解析)

基本网络请求使用的代码:

// request,根据项目的需求去组装请求的内容后,生成的 URLRequest
Alamofire.request(request).responseJSON(completionHandler: { (response) in 

}

1. 发起请求的源码 (举例:普通请求流程)

// 普通请求
public func request(
    _ url: URLConvertible,
    method: HTTPMethod = .get,
    parameters: Parameters? = nil,
    encoding: ParameterEncoding = URLEncoding.default,
    headers: HTTPHeaders? = nil)
    -> DataRequest
{
    return SessionManager.default.request(
        url,
        method: method,
        parameters: parameters,
        encoding: encoding,
        headers: headers
    )
}
  1. 当我们发起一个普通请求后,就会调用Alamofire类中定义的 request方法,当然不止这一个方法,还有 download, upload, stream等方法, 返回的结果是 SessionManager所管理的,根据调用的方法不同,依次返回的对象为: DataRequestDownloadRequestUploadRequestStreamRequest
  2. 源码中 : SessionManager.defaultdefault 这是个单例对象, 这个对象很重要, 里面做了很多重要的工作。

2. SessionManager 的关键点解析

// 单例
    public static let `default`: SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders

        return SessionManager(configuration: configuration)
    }()
    
// 初始化做了那些工作
       public init(
        configuration: URLSessionConfiguration = URLSessionConfiguration.default,
        delegate: SessionDelegate = SessionDelegate(),
        serverTrustPolicyManager: ServerTrustPolicyManager? = nil)
    {
     //1. 自己的delegate指向为新建的SessionDelegate()
        self.delegate = delegate
	//2.  创建一个URLSession , 并将 URLSession的代理指向了 SessionDelegte 
        self.session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)

        commonInit(serverTrustPolicyManager: serverTrustPolicyManager)
    }

    private func commonInit(serverTrustPolicyManager: ServerTrustPolicyManager?) {
        session.serverTrustPolicyManager = serverTrustPolicyManager
         
        // 3. sessionDelegate 的 sessionManager 又指回了当前self, 它的内部 sessionManager为 weak,不然会有循环引用的问题, 
        delegate.sessionManager = self

        delegate.sessionDidFinishEventsForBackgroundURLSession = { [weak self] session in
            guard let strongSelf = self else { return }
            DispatchQueue.main.async { strongSelf.backgroundCompletionHandler?() }
        }
    }

通过上面的源码说明: 现在我们知道了

  1. URLSession的代理指向了 SessionDelegte
  2. sessionDelegateManager = 当前 sessionManager
    这里使用了代理转换,每个类处理专门的事情。

3. SessionManager , 发起请求关键代码

@discardableResult
    open func request(
        _ url: URLConvertible,
        method: HTTPMethod = .get,
        parameters: Parameters? = nil,
        encoding: ParameterEncoding = URLEncoding.default,
        headers: HTTPHeaders? = nil)
        -> DataRequest
    {
        var originalRequest: URLRequest?

        do {
            originalRequest = try URLRequest(url: url, method: method, headers: headers)
            // 对参数进行编码
            let encodedURLRequest = try encoding.encode(originalRequest!, with: parameters)
            // 调用request请求
            return request(encodedURLRequest)
        } catch {
            return request(originalRequest, failedWith: error)
        }
    }
    
    /// - returns: The created `DataRequest`.
    @discardableResult
    open func request(_ urlRequest: URLRequestConvertible) -> DataRequest {
        var originalRequest: URLRequest?

        do {
        	//1. 返回 URLRequest 对象 ,判断为空的目的
            originalRequest = try urlRequest.asURLRequest()
            // 2. Requestable赋值,  dataRequest继承与 request 
            let originalTask = DataRequest.Requestable(urlRequest: originalRequest!)
             //3.  task 为 URLSessionDataTask 
            let task = try originalTask.task(session: session, adapter: adapter, queue: queue)
            // 4.  初始化DataRequest
            let request = DataRequest(session: session, requestTask: .data(originalTask, task))
			// 5. 用URLSessionTask的identity作为Key, dataRequest为value. 
            delegate[task] = request
			
			//  startRequestsImmediately 默认为true, 交于request中的task 开始执行网络请求 
            if startRequestsImmediately { request.resume() }

            return request
        } catch {
            return request(originalRequest, failedWith: error)
        }
    }

// Request.swift文件中的 
    init(session: URLSession, requestTask: RequestTask, error: Error? = nil) {
        self.session = session

        switch requestTask {
        case .data(let originalTask, let task):
         // 1. 初始化DataTaskDelegate ,并指向给 taskDelegate 
            taskDelegate = DataTaskDelegate(task: task)
            self.originalTask = originalTask
        case .download(let originalTask, let task):
            taskDelegate = DownloadTaskDelegate(task: task)
            self.originalTask = originalTask
        case .upload(let originalTask, let task):
            taskDelegate = UploadTaskDelegate(task: task)
            self.originalTask = originalTask
        case .stream(let originalTask, let task):
            taskDelegate = TaskDelegate(task: task)
            self.originalTask = originalTask
        }

        delegate.error = error
        delegate.queue.addOperation { self.endTime = CFAbsoluteTimeGetCurrent() }
    }

大致流程为:
初始化 DataRequest ,并将 URLSession 指向 DataRequest,初始化DataTaskDelegate,指向 DataTaskDelegate的taskDelegate , 然后 SessionDelegate 以URLSessionDataTask的identity做为key,DataRequest作为value存储起来。 然后 交于request中的task 开始执行网络请求。

4. SessionDelegate , 收到请求关键代码

open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        if let dataTaskDidReceiveData = dataTaskDidReceiveData {
            dataTaskDidReceiveData(session, dataTask, data)
        } else if let delegate = self[dataTask]?.delegate as? DataTaskDelegate {   // 根据task的 indentity,获取到 taskDelegate ,然后执行接收到数据
            delegate.urlSession(session, dataTask: dataTask, didReceive: data)
        }
    } 


// 已经完成了本次网络请求,所调用的方法 
open func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        
        let completeTask: (URLSession, URLSessionTask, Error?) -> Void = { [weak self] session, task, error in
            guard let strongSelf = self else { return }
            // 1. 执行这个闭包
            strongSelf.taskDidComplete?(session, task, error)
            // 2. 执行TaskDelegate中的urlsession ,里面逻辑是和下载有关。
            strongSelf[task]?.delegate.urlSession(session, task: task, didCompleteWithError: error)

            var userInfo: [String: Any] = [Notification.Key.Task: task]
            // 3. 拿到TaskDelegate中的 data (mutableData)
            if let data = (strongSelf[task]?.delegate as? DataTaskDelegate)?.data {
                userInfo[Notification.Key.ResponseData] = data
            }

           // 4. 暂时没有用到,通过通知把数据发送出去,使用者去监听这个通知可拿到数据
            NotificationCenter.default.post(
                name: Notification.Name.Task.DidComplete,
                object: strongSelf,
                userInfo: userInfo
            )

            strongSelf[task] = nil
        }

        // 出错处理。 
        guard let request = self[task], let sessionManager = sessionManager else {
            completeTask(session, task, error)
            return
        }
        
        if let retrier = retrier, let error = error {
           /* 省略若干代码*/
        } else {
            // 执行上面的block 
            completeTask(session, task, error)
        }
    }
  1. SessionDelegate 接收到服务器数据返回后, 就会交于到 taskDelegate, 这个delegate,也是第三点中, 通过task的identity,存储到 sessionDelegate中, 这时候再拿出来对应的 taskDelegate 。

5. TaskDelegate , 收到请求的关键代码

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        if initialResponseTime == nil { initialResponseTime = CFAbsoluteTimeGetCurrent() }

        if let dataTaskDidReceiveData = dataTaskDidReceiveData {
            dataTaskDidReceiveData(session, dataTask, data)
        } else {
            if let dataStream = dataStream {
                dataStream(data)
            } else {  // 1. 把接收到的数据放到了mutableData成员变量中。 
                mutableData.append(data)
            }
	
	        // 进度计算, 暂时不管
            let bytesReceived = Int64(data.count)
            totalBytesReceived += bytesReceived
            let totalBytesExpected = dataTask.response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown

            progress.totalUnitCount = totalBytesExpected
            progress.completedUnitCount = totalBytesReceived

            if let progressHandler = progressHandler {
                progressHandler.queue.async { progressHandler.closure(self.progress) }
            }
        }
    }

5. 数据序列化的工作。 ResponseSerialization类,关键代码

public static func serializeResponseJSON(
        options: JSONSerialization.ReadingOptions,
        response: HTTPURLResponse?,
        data: Data?,
        error: Error?)
        -> Result<Any>
    {
        guard error == nil else { return .failure(error!) }
         // 1. 判断数据是否为空, 根据状态码
        if let response = response, emptyDataStatusCodes.contains(response.statusCode) { return .success(NSNull()) }
        //2. 判断数据是否为空,根据内容长度
        guard let validData = data, validData.count > 0 else {
            return .failure(AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength))
        }

        do {  //3. data转json 数据。 
            let json = try JSONSerialization.jsonObject(with: validData, options: options)
            //4.回调转化成json数据给调用者
            return .success(json)
        } catch {
            return .failure(AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error)))
        }
    }

我们在来回顾下调用方法,

// request,根据项目的需求去组装请求的内容后,生成的 URLRequest
Alamofire.request(request).responseJSON(completionHandler: { (response) in 

}

这里可能有个疑问,为什么这里可以使用链式调用, 这里因为 Alamofire.request(request) 返回的是一个DataRequest对象,而responseJSON,是对DataRequest的扩展,所以可以直接调用。

总结

上面说的还很绕的,我通过打断点,追流程,大概总结下,发送一个普通请求,到底经过了那些步骤

  1. Alamofire.swift 文件中的方法 ,对外的request方法
@discardableResult
public func request(_ urlRequest: URLRequestConvertible) -> DataRequest { }
  1. SessionManager.swift文件中的方法 ,内部的 request方法
@discardableResult
    open func request(_ urlRequest: URLRequestConvertible) -> DataRequest { }
  1. request.swift文件中的方法 ,发送request网络请求
open func resume() {}
  1. SessionDelegate.swift文件中的方法, 网络回调数据
open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
  1. TaskDelegate.swift文件中的方法, 数据存储,进度计算
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { }
  1. SessionDelegate.swift 文件中的方法, 本次网络请求结束 ,相关的处理
open func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { }
  1. ResponseSerialization.swift文件中的方法 , 数据的序列化处理
public static func jsonResponseSerializer(
        options: JSONSerialization.ReadingOptions = .allowFragments)
        -> DataResponseSerializer<Any> {}
  1. 处理好的json数据 闭包 ( Result : 成功或者失败)传递给调用者。

上面有个疑问? 网络数据完毕后,是如何跑到序列化闭包里面,并返回数据?

这里用到了队列,提前将网络数据装入了队列中,网络数据接收完毕后,再调用起队列,执行任务。

核心的位置: 除了delegate任务分离外, 还有 队列任务用的很巧妙。

在还没有收到网络数据返回前,就将response里面的相关数据, 以闭包的方式加入到 OperationQueue ,代码如下:

//1. TaskDelegate.swift  OperationQueue的初始化, 默认任务是挂起的, 这里很重要
init(task: URLSessionTask?) {  
        _task = task

        self.queue = {
            let operationQueue = OperationQueue()

            operationQueue.maxConcurrentOperationCount = 1
            // 1. 默认任务挂起
            operationQueue.isSuspended = true
            operationQueue.qualityOfService = .utility

            return operationQueue
        }()
    }

// 2. ResponseSerialization.swift中把 response相关数据打包成block,并放入队列中,等待后面队列的调用。 
@discardableResult
    public func response<T: DataResponseSerializerProtocol>(
        queue: DispatchQueue? = nil,
        responseSerializer: T,
        completionHandler: @escaping (DataResponse<T.SerializedObject>) -> Void)
        -> Self
    {
        // 
        delegate.queue.addOperation {
            let result = responseSerializer.serializeResponse(
                self.request,
                self.response,
                self.delegate.data,
                self.delegate.error
            )

            var dataResponse = DataResponse<T.SerializedObject>(
                request: self.request,
                response: self.response,
                data: self.delegate.data,
                result: result,
                timeline: self.timeline
            )

            dataResponse.add(self.delegate.metrics)

            (queue ?? DispatchQueue.main).async { completionHandler(dataResponse) }
        }

        return self
    }

// 3. 队列的激活, SessionDelegate 中调用完成本次网络请求的回调方法中调用了 TaskDelegate 

// sessionDelegate.swift 网络返回数据结束

```swift
open func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { }

// TaskDelegate.swift 激活队列

@objc(URLSession:task:didCompleteWithError:)
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if let taskDidCompleteWithError = taskDidCompleteWithError {
            taskDidCompleteWithError(session, task, error)
        } else {
            if let error = error {
                if self.error == nil { self.error = error }

                if
                    let downloadDelegate = self as? DownloadTaskDelegate,
                    let resumeData = (error as NSError).userInfo[NSURLSessionDownloadTaskResumeData] as? Data
                {
                    downloadDelegate.resumeData = resumeData
                }
            }
             // 激活队列,开始执行网络数据的序列化
            queue.isSuspended = false
        }
    }