Alamofire学习 - Response

前言

在前面几篇内容中已经大体介绍了AlamofireRequest请求,当一个Request完成的时候,下一步 确定要处理服务器返回的响应数据。本篇内容就记录一下学习处理响应数据Response的内容。json

Response

先来一个简单的代码例子🌰看一下下:swift

SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .response { (response) in
                debugPrint(response)
        }
复制代码

咱们都知道Alamofire可使用链式访问,那就搞点事作😏,把requestresponse换一下,先进行response,再进行request,换了以后会发现根本不可能😞。这就说明了request必需要在response以前访问,这也提现了request的重要性安全

好了,在皮一下以后,回到代码来看,看一下这个response是怎么实现的:bash

这里能够看到 response的任务是加入到了 delegate.queue.addOperation,这个 delegate.queue就是在发起 request以后,建立的 TaskDelegate会默认初始化一个挂起队列。(具体请看上篇 时间轴部分)而后在 request请求 Complete以后再取消队列的挂起,保证了队列中的任务所有是在 request请求完成以后进行的, 这一样也更加说明了request必需要在response以前访问。

而后任务被交给了主队列(毕竟开发者有可能利用response进行UI的更新),能够看到在这里并无对response进行序列化,而是初始化了一个DefaultDataResponse类的对象,服务器

DefaultDataResponse是用来保存self.requestself.responseself.delegate.dataself.delegate.errorself.timelineself.delegate.metrics 属性,并把初始化的DefaultDataResponse对象返回给completionHandler 闭包。(有点相似于Model,通常来讲,在swift中,若是只是为了保存数据,那么应该把这个类设计成structstruct是值传递,所以对数据的操做更安全。除了定义须要保存的数据属性后,必须设计一个符合要求的构造函数。), 闭包

小总结:app

  • request(该响应来源于那个请求)
  • response(服务器返回的响应)
  • data(响应数据)
  • error(在请求中可能发生的错误)
  • timeline(请求的时间轴封装)
  • _metrics(包含了请求和响应的统计信息)

这些数据都不是由response来建立的,它只有使用权。也就是说response只是一个数据的保存信息者,把各类数据化零为整返回给用户。函数

Response序列化

Alamofire中把Request分为了4类:post

  • DataRequest
  • DownloadRequest
  • UploadRequest
  • StreamRequest

由于有四种不一样的Request类型,StreamRequest咱们先a按下不表,对于UploadRequest来讲,服务器响应的数据比较简单,就响应一个结果就行,所以不须要对它的Response专门进行封装。所以,Alamofire设计了2种与之相对应的Response类型学习

  • DefaultDataResponse / DataResponse
  • DefaultDownloadResponse / DataResponse

细心的你必定会发如今DataRequest 的扩展的中会有两个response方法,(第一个response方法在上面👆已经给出,下面👇贴出第二个response

在这个序列化的 response方法内部,能够看到会先进行一个 serializeResponse的操做获得一个结果 result,而后在初始化一个 DataResponse对象用来保存 self.requestself.responseself.delegate.dataresultself.timelineself.delegate.metrics这些数据,并把 DataResponse对象返回给 completionHandler 闭包。

若是你对比这两个response方法,聪明而优秀的你就会发现这两个方法的不一样之处:

request请求完成以后,获取到的是没有通过序列化后的数据,若是调用了没有序列化的response方法,DefaultDataResponse/DefaultDownloadResponse。若是调用了序列化的response方法,须要传入一个泛型的responseSerializer 参数,返回的就是DataResponse

能够看到这个序列化的 response方法遵循了 DataResponseSerializerProtocol协议,下面经过源码看一下这个协议的具体实现:
在这个协议内部有一个序列化函数 serializeResponse,并返回一个类型为 SerializedObject的Result,那么也就是说序列者只须要遵循这个协议就能够了:因此就有了这样一个用序列化函数 serializeResponse做为参数来初始化,而且保存序列化函数的 DataResponseSerializer类;

从这里咱们知道调用序列化函数serializeResponse会返回一个Result,并且在前面也已经说过,在序列化的response方法内部,看到会先进行一个serializeResponse的操做获得一个结果result

能够看到关于 Result的结果只有两种:成功和失败。成功就把序列化完成的数据返回,失败就返回一个 error信息。

Response扩展

若是我想把请求的结果序列化成json类型或者String类型的,怎么办,难道调用序列化的response方法拿到返回的内容以后,用户此时再去本身作序列化成json类型或者String类型的内容?怎么可能,霸气侧漏的Alamofire早就已经都作好了。

SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .response { (response) in
               
        }
SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .responseData { (responsedata) in
              
        }
SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .responseString { (responseString) in
                
        }
SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .responseJSON { (responsejson) in
                
        }
SessionManager.default.request("https://www.douban.com/j/app/radio/channels")
            .responsePropertyList{ (responselist) in
                
        }
复制代码

responseData

responseData在其方法内部是直接调用了 response的序列化方法,那么也就是和 response同样,把数据序列化为 Data类型也就是 Result

这里传入的序列化器responseSerializer的参数是DataRequest.dataResponseSerializer(),下面来看一下dataResponseSerializer()

返回的就是 DataResponseSerializer 类型的序列化器, DataResponseSerializer这个类前面已经介绍过,它是用来保存序列化函数的,关键在于 Request.serializeResponseData

这里会根据序列化的成功和失败来返回数据,返回 .success(validData)或者 .failure(error信息)

注解:emptyDataStatusCodes

若是 HTTP response code204或者 205,就表示 Datanil.

关于responseStringresponseJSONresponsePropertyList在内部是如何实现的,在这里就不一一列出来了,基本和responseData的套路同样,有兴趣的大佬能够借助源码去看一下。

总结

实际上这个response并非咱们常见的那种response,它只是一个保存内容的载体,它把requestresponsedataerrortimeline_metrics 这些数据所有收集整合起来,放到本身身上,而后一块儿返回给用户,这样用户在外面能够拿到他想要的任何数据,这是多么牛X的处理方式。

相关文章
相关标签/搜索