阅读 34

Alamofire-Response

response为数据请求响应结果,封装了URLRequest、时间轴、请求错误信息,请求成功的数据等信息,方便开发人员取用。

一、业务层获取响应数据

Alamofire.request(url,method: .post,parameters: nil)
    .response{ response in
    print("response:\(response)")
}
复制代码
  • response方法通过闭包向外传递响应数据

1、response-方法

方法实现在ResponseSerialization.swift文件中,是对响应结果的封装,提供序列化和不序列化请求结果的方法,其实都是对结果的一个处理封装,因此都放在该文件是合理的。下面看一下默认响应处理:

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
}
复制代码
  • 该方法为DataRequest的扩展方法,返回self,可以继续链式调用,为方便调用,在Request类中这种写法比较常见
  • 创建了DefaultDataResponse对象,并初始化,将请求过程中所有参数整合

该方法在序列化文件中,都是对Request相关子类的扩展,以便于业务层调用。前面有讲到过,Request是面向业务层的,提供responseJSON、downloadProgress、response等方法。

DefaultDataResponse为一个结构体,在Response.swift文件中,是默认的存储结构。

2、Response-结构体

Response.swift中声明了多个结构体,应对不同的使用场景。分类如下:

DefaultDataResponse
DataResponse
DefaultDownloadResponse
DownloadResponse
复制代码

在业务层调用的response中对应的为DefaultDataResponse结构体,此处没有做序列化处理,只是对数据进行整合。业务层的方法调用和内部结构体的联系如下:

1、response{ response in } -> DefaultDataResponse 只做数据整合 2、responseJSON{ response in } -> DataResponse 对请求数据做序列化处理再整合 3、downloadProgress.response -> DefaultDownloadResponse 整合存储下载相关信息 4、downloadProgress.response(responseSerializer) -> DownloadResponse 整合存储下载相关信息

为什么没有upload对应的结构体呢,因为upload返回结果就是普通的数据返回,以上提供的方法便可公用。

通过Request对象的一步步调用,最终数据会处理未Response的形式,通过闭包调用向业务层发送response类型消息。

二、DataResponseSerializer-序列化器

Request类中提供了序列化处理和非序列化处理,可以根据需要来调用。下面看一下,序列化器是如何序列化的。方法入口如下:

Alamofire.request(url,method: .post,parameters: nil).responseJSON {
    (response) in
    switch response.result{
    case .success(let json):
        print("json:\(json)")
        break
    case .failure(let error):
        print("error:\(error)")
        break
    }
}
复制代码
  • responseJSON就是获取一个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
    )
}
复制代码
  • jsonResponseSerializer实际上是一个函数指针,供response内部调用,通过该函数来处理数据

jsonResponseSerializer实现:

public static func jsonResponseSerializer(
    options: JSONSerialization.ReadingOptions = .allowFragments)
    -> DataResponseSerializer<Any>
{
    return DataResponseSerializer { _, response, data, error in
        return Request.serializeResponseJSON(options: options, response: response, data: data, error: error)
    }
}
复制代码
  • 实现闭包连接,共ResponseSerialization中的response方法内部调用

最终调用serializeResponseJSON方法来序列化数据。代码如下:

public static func serializeResponseJSON(
    options: JSONSerialization.ReadingOptions,
    response: HTTPURLResponse?,
    data: Data?,
    error: Error?)
    -> Result<Any>
{
    //代码省略
    do {
        let json = try JSONSerialization.jsonObject(with: validData, options: options)
        return .success(json)
    } catch {
        return .failure(AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error)))
    }
}
复制代码
  • 这里就能看到我们熟悉的身影,通过JSONSerialization对数据做序列化处理
  • 根据序列化结构返回.success.failure

以上方法的调用如下:

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
}
复制代码
  • 调用序列化方法,传入必要参数,对数据序列化处理,最终返回一个Result的枚举
  • 将序列化产生的枚举result封装至dataResponse中,此时序列化到响应就全都完成
  • 将结果通过闭包在主队列中向外发送

三、Result

是一个枚举,在response中传递的既是该枚举类型的变量,通过变量来判断数据请求是成功还是失败。

.responseJSON { (response) in
    switch response.result {
        case .success(let json):
            print("json:\(json)")
            break
        case .failure(let error):
            print("error:\(error)")
            break
    }
}
复制代码

只有json序列化之后才会有以上枚举变量,来通知业务层序列化成功还是失败。

四、总结

  • 1、response在序列化器ResponseSerialization中初始化;
  • 2、序列化器实际上是Request类的扩展,方便通过闭包向业务层传递请求结果;
  • 3、序列化器的Request的扩展方法中都返回self,以便于链式调用;
  • 4、response帮助我们统一管理请求过程中的数据,请求成功、失败、时间轴等等,便于业务层处理;
  • 5、Response为不同请求类型,提供不同的结构体类型来管理数据。