Swift开发

Alamofire的Request解析

2018-09-07  本文已影响154人  Lucas汪星人
女神镇楼

上一篇我们主要说了一下Alamofire中对一个普通的DataRequest的响应序列化的步骤。这次我们针对Requset的一个过程简要分析下

首先我们看下一个普通的请求的流程经过了哪些步骤

之前分析过Alamofire中的静态方法都是调用SessionManager里面的方法,SessionManager里的default存放着默认的session,而SessionDelegate则实现了session的代理。

    private func commonInit(serverTrustPolicyManager: ServerTrustPolicyManager?) {
    session.serverTrustPolicyManager = serverTrustPolicyManager
     ///这里设置了代理
    delegate.sessionManager = self

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

再来看看SessionManager里面

首先声明了许多闭包,如果你想自己定义你的接收响应的逻辑你可以实现这些闭包

// MARK: URLSessionDelegate Overrides

/// Overrides default behavior for URLSessionDelegate method `urlSession(_:didBecomeInvalidWithError:)`.
open var sessionDidBecomeInvalidWithError: ((URLSession, Error?) -> Void)?

/// Overrides default behavior for URLSessionDelegate method `urlSession(_:didReceive:completionHandler:)`.
open var sessionDidReceiveChallenge: ((URLSession, URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?))?

再来看看里面代理方法的实现

    /// Tells the delegate that the data task has received some of the expected data.
///
/// - parameter session:  The session containing the data task that provided data.
/// - parameter dataTask: The data task that provided data.
/// - parameter data:     A data object containing the transferred data.
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:request]来获取到request,调用其taskDelegate实例对象的方法,将数据传递给了TaskDelegate
        delegate.urlSession(session, dataTask: dataTask, didReceive: data)
    }
}

可以看到将数据传递到了TaskDelegate里,再来看下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 {
        ///如果实现了request的stream方法,则这里将数据通过闭包传递
            dataStream(data)
        } else {
        ///否则存储数据
            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) }
        }
    }
}

我们可以看到,针对一个普通的Data请求的话,这里的data就保存了返回的响应数据。

override var data: Data? {
    if dataStream != nil {
        return nil
    } else {
        return mutableData
    }
}

所以后面在序列化返回数据的时候我们可以看到

这里的data就是获取的request.delegate.data
var dataResponse = DataResponse<T.SerializedObject>(
            request: self.request,
            response: self.response,
            data: self.delegate.data,
            result: result,
            timeline: self.timeline
        )

总的来说,一次普通的请求流程是


分步骤详细解析

我们还是从最基础的DataRequest的一个方法来逐行进行分析

open func request(_ urlRequest: URLRequestConvertible) -> DataRequest {
    var originalRequest: URLRequest?

    do {
        originalRequest = try urlRequest.asURLRequest()
        let originalTask = DataRequest.Requestable(urlRequest: originalRequest!)

        let task = try originalTask.task(session: session, adapter: adapter, queue: queue)
        let request = DataRequest(session: session, requestTask: .data(originalTask, task))

        delegate[task] = request

        if startRequestsImmediately { request.resume() }

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

这里通过传递一个URLRequestConvertible类型的参数来开始一个请求

URLRequestConvertible是一个协议,只有一个asURLRequest的方法,所以我们知道,你可以传任意类型哪怕是一个PigClass类,只要实现这个协议方法能够返回URLRequest即可,从这里我们可以看到但凡是后缀是Convertible的协议都是类似于这样的便利方法,就像我们前面分析过的URLConvertible一样

单纯的技术分析,也没啥图。如果这都能从头看到尾的话,我佩服你。哈哈。

这次简单通过一个DataRequest来分析了下请求的一个过程,后面还会写一篇文章来分析下别的类型的Request的设计思路和我对于Alamofire的一篇最终总结吧。希望能学习到作者的代码设计风格。

最终

太轻易得到的往往都不会去珍惜,真正失去了却又后悔莫及。

联系方式

上一篇 下一篇

猜你喜欢

热点阅读