项目干货挖掘3——怎么去封装一个网络层?

前言

我之前已经写过一篇有关网络层的笔记:关于网络层的设计(一)——和业务层的对接。在这篇笔记中主要解释了网络层设计时所要考虑的因素。给出的代码例子是以block回调的,以AFNetworking请求网络的,而且结构是离散型的。
那本篇我们选择处处与之相对立,即以delegate回调给业务层数据,自己封装NSURLConnection来请求网络,结构采用集约型,而且更全面细致:加入了网络超时的处理,请求队列的控制,完善的公共参数等。

 


HomeViewController.m

这是业务层的代码。业务层所有的网络请求都通过ConnectManager里的该方法完成,这就是所谓集约型结构,所有的业务请求均由一个方法完成,这样的话开发效率可能会更高,毕竟只使用这个方法嘛。
而且数据从网络层交付到业务层是通过delegate回调方法的形式,这样的话若在同一个ViewController有多个不同接口的网络请求,则需要在代理方法里判断接口requestInterface,不同接口分别做不同处理。这也是和block回调不同的地方,block方式是每个接口都对应一个block回调,而delegate则只有一个代理方法,所以需要在代理方法里带上requestInterface用以判别区分出不同的接口。


ConnectManager.h

可以看到我们声明了生成实例的单例方法,并声明了那个给业务层调用请求网络的方法。我们还定义了ConnectManagerDelegate协议,业务层的VC为其代理者,即上面代码看到的实现。
除此外,我们还定义了两个枚举变量,第一个是请求方式HttpType,第二个是代表接口的枚举变量,所有的接口都在此定义成枚举变量。业务层传入的接口参数便为接口的枚举变量。


ConnectManager.h

我们可以看到该类主要完成了请求队列的控制,可以控制在将当前请求加入请求队列时,是否清空请求队列中的所有请求,或者只是从请求队列中把旧的该请求清除。
通过调用HTTPConnect的方法,生成网络连接的对象,并开始连接(等下看HTTPConnect类的详情)。
而且它作为HTTPConnect的代理,实现了HTTPConnectDelegate协议的方法。并将数据转换成了RequestResult,并调用了ConnectManagerDelegate协议的方法,将其回调给业务层。

注意接口返回格式的约定:这里需要多说几句的是。项目开始前,后台会在接口文档中写明接口统一返回格式。所有的接口都遵循这个格式。比如,我们当前的项目,后台在接口文档中就给出了“接口返回格式”:返回的json数据最外层有hb两个key,分别意为headbody,在head的value又是一个字典,分别有code,msg,time三个key,分别代表错误码信息提示,服务器时间。而在body里则是真正需要的数据。
根据这个约定,我们创建了RequestResultmodel对象用以封装返回数据(后面给出了RequestResult的代码)。

对于Null值的处理:若后台返回的某个字段是Null,表示该字段为空,这样直接使用既不友好,也比较危险。不友好之其一为若要显示在UI上便会显示为<null>,其二为在判断该字段是否为空的地方得要这样:if([awarder.awarderId isKindOfClass:[NSNull class]]),比较麻烦。危险之处是在OC中若字典以这样的方式@{@"key1":@"value1",@"key2":@"value2"};建立,此时若value1为空,程序执行到此直接会崩掉。
所以我们需要对后台返回的json数据都要做Null值处理。我们可以在预编译文件中定义一个宏,若值为NSNull则将其置为@""

 

988593-79ea99d50966fc3d

 


HTTPConnect.h

可以看到HTTPConnect是完成网络连接和数据请求及响应的核心。在此,我们创建网络连接的对象,并控制开始连接和断开连接。
值得注意的是HTTPConnect是继承自NSOperation的。一个网络连接的对象便是一个“操作”,每个连接对象都会加入到ConnectManager的请求队列_operationQueue中。
我们还定义了很多HTTPConnect的属性,主要为网络响应返回的数据,之所以作为其公开的属性,是因为要回调给ConnectManager,所以得暴露为公开的属性。
除此外,我们还定义了HTTPConnectDelegate协议。


HTTPConnect.m

首先我们在初始化方法里,初始化了一些变量,并拼接了各种参数,生成了网络连接对象_urlConnection。然后实现了startConnectcancelConnect方法。值得注意的是我们加入了网络请求超时的控制,若开始连接后,若计时器撑到了30s还没有被销毁,说明网络请求超时了。
该类是网络连接的核心,我们实现了NSURLConnectionDataDelegate协议的方法,在该协议的方法里,网络数据主要在这些协议方法里进行响应,这是重点。我们对响应的数据进行了一些处理,并赋值给HTTPConnect的属性,然后调用HTTPConnectDelegate协议的方法,回调给ConnectManager,注意,这些协议的方法均有参数httpConnect对象,这样便把其属性,即网络响应返回的数据回调给了ConnectManager;而在ConnectManager中上面我们已经说了,会把数据转换为RequestResultConnectManager再调用其对应的协议方法,便将RequestResult形式的数据回调给业务层。
这样就完成了网络响应的数据从NSURLConnectionDataDelegate的实现方法到HTTPConnectDelegate的实现方法,再到ConnectManagerDelegate的实现方法。即网络数据从HTTPConnectConnectManager,再到HomeViewController
嗯,整个流程就是这样。


RequestResult.h 和 RequestResult.m


补充

上面我们在生成网络连接对象时将公共参数部分的代码省略了,它们应该装入到网络请求的HTTP请求头中。一般公共参数有token(登录凭证)、UA(设备基本信息)、IMEI(设备的唯一标示)等。
代码补上,如下:

 

1 2 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部