Alamofire 关于Response的思考

偶尔善良 提交于 2019-11-28 16:09:06

Alamofire 关于Response的思考。

你好,我是Emma,今天我们开启对Alamofire 关于Response的思考。主要的思考方向以下方示例为切入点。

示例:

SessionManager.default.request(urlString)
    //默认的请求
    .response(completionHandler: { (dataResponse) in
        dataResponse.response
    })
    //自定义序列化的请求
    .response(responseSerializer: DataResponseSerializer<String>.init(serializeResponse: { (request, response, data, error) -> Result<String> in
        print("原始数据:\(response)")
        return .success("成功啦")
    })) { (dataResponse) in
         print(dataResponse)
    }
    //系统封装过的序列化请求
    .responseJSON { (jsonResponse) in
        print(jsonResponse)
}

###1.Alamofiren中Response这个角色的作用是什么?
首先在查看源码之前,通过上面的代码我们思考一下,我们认为的Response是用来做什么的?这时候我们很有可能由于使用Alamofire的惯性会认为这个Response的作用是解析result中返回的数据的。这个观点我们用代码验证并订正。
进入Response方法:

1.Response返回的是一个闭包,闭包的参数是DefaultDataResponse,这个包相当于是`{ (lgDataResponse) in
        lgDataResponse
    }`这个包的处理。
2.添加异步请求队列
`delegate.queue.addOperation {}`
3.返回主线程
`(queue ?? DispatchQueue.main).async {}`
4.创建对象
`var dataResponse`
5.该对象的来源:源方法的声明,方法中的属性,属性的调用,属性的初始化等函数方法的具体下层操作。
//DefaultDataResponse是一个总的结构体,里面保存了很多属性,那么思考这些属性的数据是从什么地方来的呢?
DefaultDataResponse(
                request: self.request,
                response: self.response,
                data: self.delegate.data,
                error: self.delegate.error,
                timeline: self.timeline
            )
总结从上面可以看出Response作用典型的是存储,更像model一些。

###2.Alamofiren中Response保存了什么?

@discardableResult
public func response(queue: DispatchQueue? = nil, completionHandler: @escaping (DefaultDataResponse) -> Void) -> Self {
    delegate.queue.addOperation {
        (queue ?? DispatchQueue.main).async {
            var dataResponse = DefaultDataResponse(
                request: self.request,
                response: self.response,
                data: self.delegate.data,
                error: self.delegate.error,
                timeline: self.timeline
            )

            dataResponse.add(self.delegate.metrics)

            completionHandler(dataResponse)
        }
    }

    return self
}

####1.Request的来源:
response中的request是通过传过来的是什么类型来保存好响应的request。

/// The request sent or to be sent to the server.
open override var request: URLRequest? {
    if let request = super.request { return request }
    if let requestable = originalTask as? Requestable { return requestable.urlRequest }

    return nil
}

####2.response: self.response的来源:

类似于参数 = 值

左边的Response是public let response: HTTPURLResponse?意在表示对于URL服务器给出的返回,只是结构体保存的一种存储方式。

右边的self.response是服务器返回的真正的任何请求
open var response: HTTPURLResponse? { return task?.response as? HTTPURLResponse }
通俗的将调用的时候:

//lgDataResponse相当于DefaultDataResponse,
//response相当于左边的参数。
//而连起来用lgDataResponse.response这个的值就相当于右边的self.response,即服务器返回的任意的响应。
.response(completionHandler: { (lgDataResponse) in
    lgDataResponse.response
})

####3.data: self.delegate.data的来源?这里的self.delegate指的是哪个代理?或者说这里将什么data值进行了保存?

class DataTaskDelegate: TaskDelegate, URLSessionDataDelegate {
    override var data: Data? {
        if dataStream != nil {
            return nil
        } else {
            return mutableData
        }
    }
}

data的来源是mutableData,这里的代理是DataTaskDelegate或者是DownloadTaskDelegate代理,具体是请求的时候task是什么请求类型。
mutabledata的处理:

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 {
            mutableData.append(data)
        }
        。。。
    }
}

DataTaskDelegate中的

func urlSession(){

}

var dataTaskDidReceiveResponse: ((URLSession, URLSessionDataTask, URLResponse) -> URLSession.ResponseDisposition)?
var dataTaskDidBecomeDownloadTask: ((URLSession, URLSessionDataTask, URLSessionDownloadTask) -> Void)?
var dataTaskDidReceiveData: ((URLSession, URLSessionDataTask, Data) -> Void)?
var dataTaskWillCacheResponse: ((URLSession, URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?)?

这些变量的声明都是有联系的这个设计思想是什么?我看dataTaskDidReceiveData在SessionDelegate中也有,并且类型时open var 的我尝试在写SessionDelegate.dataTaskDidReceiveData这个没有提示,这个是做什么用的?在DataTaskDelegate中,这些声明用来做什么的?

最关键的是:无法理解为什么mutableData.append(data)要写在这里?我目前字面上的理解是数据任务接收到数据,数据都是不完整的,然后mutableData是将数据拼完整,这个理解有问题吗?如果数据接收完了之后就调用上面这个分支

if let dataTaskDidReceiveData = dataTaskDidReceiveData {
//回调出去
        dataTaskDidReceiveData(session, dataTask, data)
    } 
    

就将数据传递出去。
简单说就是对外闭包是否实现了?如果实现了就证明用户要自己处理。

if let dataTaskDidReceiveData = dataTaskDidReceiveData {
    dataTaskDidReceiveData(session, dataTask, data)
} else {
    if let dataStream = dataStream {
    //判断是否传输完毕
        dataStream(data)
    } else {
    //传输完毕,回调出去,否则一直拼接
        mutableData.append(data)
    }
    。。。
}

SessionDelegate 中dataTaskDidReceiveData方法open var是对外提供的方法,这个可以提供外面调用,现在这个taskDelegate中的方法不是open var的也可以我也没有看见dataTaskDidReceiveData方法在哪里回调了啊?

我的理解里,不是completionHandler(disposition)调用这种逃逸闭包的时候才执行外面闭包实现中的方法吗?就像dataTaskDidReceiveResponse这个属性的session方法实现一样。这里面就有将completionHandler(disposition)回调,可是dataTaskDidReceiveData中就没有completionHandler(disposition)啊怎么回调出去的?
待续待续。。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!