美文网首页
Alamofire解析之响应

Alamofire解析之响应

作者: 狂奔的胖蜗牛 | 来源:发表于2019-12-16 09:50 被阅读0次

Alamofire中如何响应请求的:

Alamofire
.request("https://ip.cn")
.responseData { respons in //响应请求
     print(String(bytes: respons.data!, encoding: .utf8)!)
}

1 看看源码

先去DataRequest的responseData()方法内部看看源码:

    @discardableResult
    public func responseData(
        queue: DispatchQueue? = nil, //执行响应闭包的队列,默认为空
        //解析完成后执行的闭包
        completionHandler: @escaping (DataResponse<Data>) -> Void)
        -> Self
    {
        return response(
            queue: queue,
            responseSerializer: DataRequest.dataResponseSerializer(),
            completionHandler: completionHandler
        )
    }
  • queue参数:
    解析完毕后的闭包在哪个队列执行
  • completionHandler参数:
    解析完毕后,调用的闭包,请求结果会以Data的形式返回。
  • 方法内部:
    在方法内部,调用了自身的response()方法。

接下来,看看response()方法的源码:

    @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
            )
            //生成闭包中的DataResponse
            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
    }
  • responseSerializer参数:
    响应是如何解析的,使用的是DataRequest.dataResponseSerializer()
  • 方法内部:
    具体操作看注释,方法内部主要作用是:给请求队列添加解析的操作,操作完毕后在给定的队列中调用传入的闭包。
  • 通过源码可以看出,闭包中DataResponse参数中,request、response、data、result、timeline这几个属性,是通过请求的返回生成的,大多数我们也只是需要data属性。
  • 我们还可以知道,执行闭包的队列我们是可以自己指定的,比如需要闭包在指定的子线程执行,传入子线程即可。否则默认是在主线程执行闭包。

2 看看默认的解析器内部都干了什么

public static func dataResponseSerializer() -> DataResponseSerializer<Data> {
        return DataResponseSerializer { _, response, data, error in
            return Request.serializeResponseData(response: response, data: data, error: error)
        }
    }

这个方法是DataRequest扩展的一个方法,方法内部初始化了一个DataResponseSerializer的实例,传入了一个闭包,闭包中调用了Request的类方法serializeResponseData()。


看起来很绕,我们一步一步来看,先看看闭包中调用的Request的类方法serializeResponseData()。

    public static func serializeResponseData(response: HTTPURLResponse?, data: Data?, error: Error?) -> Result<Data> {
        //判断请求是否发生了错误
        guard error == nil else { return .failure(error!) }
        //取出response,如果是204、205状态码,直接返回空数据
        if let response = response, emptyDataStatusCodes.contains(response.statusCode) { return .success(Data()) }
        //取出data
        guard let validData = data else {
            return .failure(AFError.responseSerializationFailed(reason: .inputDataNil))
        }
        //执行成功的闭包
        return .success(validData)
    }

做了哪些操作看注释。总结一下,本方法作用就是对原生的请求response进行响应的处理。


接下来看看DataResponseSerializer这个结构体。

public struct DataResponseSerializer<Value>: DataResponseSerializerProtocol {
    public typealias SerializedObject = Value
    public var serializeResponse: (URLRequest?, HTTPURLResponse?, Data?, Error?) -> Result<Value>
    public init(serializeResponse: @escaping (URLRequest?, HTTPURLResponse?, Data?, Error?) -> Result<Value>) {
        self.serializeResponse = serializeResponse
    }
}

可以看到,该方法内部使用了一个属性保存传入的解析方法,在后续需要解析时直接调用属性进行解析。

3 总结

通过源码,我们可以知道如下几件事:
1.调用responseData()方法时,我们可以指定闭包和闭包执行的线程。
2.responseData()方法内部是调用自身的response()方法,也就是说,response()这个方法我们可以自己调用,传入自己需要的response解析器满足自定义需求。
3.可以通过respons.metrics属性获得请求过程中详细的信息。
4.依次类推,responseJSON、responseString等方法,也是这样。

相关文章

网友评论

      本文标题:Alamofire解析之响应

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