项目越来越大,发现原来项目的网络架构扩展性比较差,想来想去,还是去了解一下新的架构。而正好,有个项目要把整个API换新的,于是改!!!!
想必绝大部人都看过casatwy大神iOS应用架构谈 网络层设计方案这个文章。我也是参考了他的架构,同时也看了猿题库网络库的源码,总的来说,它们俩的思路差不多,但实现有些许差别。
集约型老架构
之前的架构采用的是集约型
。
我们从下往上看
- 一个HttpClient,里面用AFNetwork封装POST和GET等方法,这一层主要是网络调用。
- 然后上一层的BaseAPI是依赖于HttpClient,它有个方法是负责调用API的,可以把Token参数放在这里添加后再调用API。每个业务API都必须继承于它,在业务API中,负责每个的API的网络请求地址和请求参数,调用BaseAPI的方法发出请求。
- 而在NetworkHandler里面主要是对数据的过虑与封装,例如:
1 | { |
像从BaseAPI返回的是这种类型的JSON数据, code=200
为调用成功,否则失败。所以在BaseNetworkHandler里面可以统一处理失败的请求。其次,在各个业务的Handler里面,可以对调用成功的数据转化为Model。
像这种架构的话,有两个问题:
- 取消请求,麻烦!
- 缓存数据,麻烦!
- 想单独对某个请求进行AOP,麻烦!
命令型新架构
为了以后更好的扩展,决定改成命令型
。
命令型
:首先我会定义好一个网络请求代理器
,里面可以用AFNetwork,也可以用原生的。它的工作是接收到各式各样的请求命令
,根据命令里信息,然后放到进队列发起请求。
然后在外面就会定义各种请求命令
,请求命令
里面包含着请求参数、请求地址、请求方法、请求头等一些相关的信息。
当然我们可以弄个请求命令的基类:BaseManager
。里面定义了各种需要实现的协议。(多说一句:真想把java的抽像类给搬过来)。在基类有startRequest
这样的方法,它的作用就是把命令往网络请求代理器
中丢。
下面分两个问题来讲讲写命令型
怎么写好一个网络请求代理器呢
- 向外面只需要暴露接收命令的接口以及取消的接口
- 在里面必须把发请求部分要封装好,便于以后替换第三方库
- 持有每个请求,且为每个请求生成ID,便于取消
这个是从casatwy的RTNetworking里面CTApiProxy.h
类找来的一段代码。
1 | /** 这个函数存在的意义在于,如果将来要把AFNetworking换掉,只要修改这个函数的实现即可。 */ |
可以看到持有每个请求的ID并返回。便于取消。本身也持有了每个请求的ID
如何写一个消息命令呢?
话不多说,show you the code:
1 | #import <Foundation/Foundation.h> |
同样也是从大神的库里面拿出一份代码,很多东西我都删了,只留下主要的部分代码。
像CTAPIManager
,所有的派子生都必实现它,为什么用协议而不用继承呢?因为协议是强迫你实现,而继承总会忘了实现一些方法(还是很想说你java的抽像方法)。里面有methodName(请求地址)、requestType(请求类型)、shouldCache(是否缓存)等等。
像CTAPIManagerApiCallBackDelegate
的是就API的回调了,一般可以在在ViewController实现。
还有其他的一些东西,我觉得得去认认真真去看看源码就会懂了。
不过我有一点跟大神不一样。那就是参数上的问题,在我的网络请求层里面,我不使用回调的方式从ViewController获取参数,我直接在APIManager持有参数。一方面不需要让ViewController持有参数,保持少量的代码。另一方面,因为很多参数都从不同的地方获取,这样子直接赋给APIManager会更方便一些。
新的架构大概感悟就这么多了,当流水账了…~ ~