美文网首页
Alamofire(5)-Response

Alamofire(5)-Response

作者: BoxJing | 来源:发表于2019-08-24 21:35 被阅读0次

前面2篇文章介绍了Alamofire里面的Request相关的知识点,本篇介绍一下Response。

直接找到基本的response源码:

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
    }

来了一个异步的DefaultDataResponse创建,点进去可以发现是一个结构体,这个东西我们可以直接理解为Alamofire为了方便数据的返回而封装的Model,把所有关于Response的数据全部保存在一起,化零为整,很好的一个面向对象的设计原则,把这个完整的数据返回给用户,用户想用什么就取什么。requestresponsetimeline好理解,Request本身都有这些东西。下面的一个data从哪里来的不得而知,慢慢追寻过去,相信都能找到delegatetaskDelegate,里面有一个data属性,但是:public var data: Data? { return nil },什么时候这个data有值了还是不知道。看下图(看看子类里是不是有处理):


点击DataTaskDelegate会发现有点意思:
override var data: Data? {
        if dataStream != nil {
            return nil
        } else {
            return mutableData
        }
    }

找了半天的data就是mutableData,全局搜一下,可以找到mutableData只有在func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)方法里有赋值:


data这样知道到后,error就简单多了,直接在工程里搜索didCompleteWithError就能找到其中一个赋值。
在这种基本的Response源码的下面会发先有一个多了result属性的dataResponse返回的response
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
    }

看到SerializedObject,都会直接想到序列化。直接来个实实在在的序列化例子:

SessionManager.default
            .request(urlStr, parameters: ["type":"1","page":"1"])
            .response(responseSerializer: DataResponseSerializer<String>.init(serializeResponse: { (reqest, response, data, error) -> Result<String> in
                print("原始数据:\(String(describing: data))")
                return .success("一个阿狸")
            })) { (boxResponse) in
                print("序列化后的数据: \(boxResponse)")
        }

也就是说我们可以不用Alamofire的默认返回值,直接预处理自己的数据模型,将返回的所有数据按照统一的标准进行封装,方便全局的调用、判断等。这个序列化是如何进去的,先看DataResponseSerializer初始化方法:
public init(serializeResponse: @escaping (URLRequest?, HTTPURLResponse?, Data?, Error?) -> Result<Value>) {
        self.serializeResponse = serializeResponse
    }

初始化的时候传进来了闭包参数,保存的是函数式,就是保存了一个代码块,这个代码块就在responseSerializer.serializeResponse这里执行掉,觉得很麻烦对不,没关系,Alamofire为我们封装了基本常用的序列化器,比如JSON:

public func responseJSON(
        queue: DispatchQueue? = nil,
        options: JSONSerialization.ReadingOptions = .allowFragments,
        completionHandler: @escaping (DataResponse<Any>) -> Void)
        -> Self
    {
        return response(
            queue: queue,
            responseSerializer: DataRequest.jsonResponseSerializer(options: options),
            completionHandler: completionHandler
        )
    }

DataRequest.jsonResponseSerializer(options: options)就是一个json序列化器,深入到最后的序列化源码:

public static func serializeResponseJSON(
        options: JSONSerialization.ReadingOptions,
        response: HTTPURLResponse?,
        data: Data?,
        error: Error?)
        -> Result<Any>
    {
        guard error == nil else { return .failure(error!) }

        if let response = response, emptyDataStatusCodes.contains(response.statusCode) { return .success(NSNull()) }

        guard let validData = data, validData.count > 0 else {
            return .failure(AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength))
        }

        do {
            let json = try JSONSerialization.jsonObject(with: validData, options: options)
            return .success(json)
        } catch {
            return .failure(AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error)))
        }
    }

此时此刻,我们自己的序列化器,也来抽出来封装一下:

let boxResponseSerlizer = DataResponseSerializer<String>.init(serializeResponse: { (request, response, data, error) -> Result<String> in
            print("原始数据:\(String(describing: response))")
            return .success("一个阿狸")
        })
SessionManager.default
      .request(urlStr, parameters: ["type":"1","page":"1"])
      .response(responseSerializer: boxResponseSerlizer) { (boxResponse) in
           print(boxResponse)
      }

就是和上面的Json序列化器一毛一样,传进去一个序列化器参数就可以了!

Alamofire的Response有四种:DataResponseDefaultDataResponseDownloadResponseDownloadDefaultResponseDefaultDataResponseDataResponse的区别就在于返回的少一个result对象,也就是说返回的数据少了一个经过处理或者说是经过序列化后的数据。

相关文章

网友评论

      本文标题:Alamofire(5)-Response

      本文链接:https://www.haomeiwen.com/subject/mnnqectx.html