iOS应用架构谈(三):网络层设计方案(上)IOS开发语言与工具

网络层在一个App中也是一个不可缺少的部分,工程师们在网络层能够发挥的空间也比较大。另外,苹果对网络请求部分已经做了很好的封装,业界的AFNetworking也被广泛使用。其它的ASIHttpRequest,MKNetworkKit啥的其实也都还不错,但前者已经弃坑,后者也在弃坑的边缘。在实际的App开发中,Afnetworking已经成为了事实上各大App的标准配置。

网络层在一个App中承载了API调用,用户操作日志记录,甚至是即时通讯等任务。我接触过一些App(开源的和不开源的)的代码,在看到网络层这一块时,尤其是在看到各位架构师各显神通展示了各种技巧,我非常为之感到兴奋。但有的时候,往往也对于其中的一些缺陷感到失望。

在安居客App的架构更新换代的时候,我深深地感觉到网络层跟业务对接部分的设计有多么重要,因此我对它做的最大改变就是针对网络层跟业务对接部分的改变。网络层跟业务层对接部分设计的好坏,会直接影响到业务工程师实现功能时的心情。

在正式开始讲设计之前,我们要先讨论几个问题:

这些问题讨论完毕之后,我会给出一个完整的设计方案来给大家做参考,设计方案是鱼,讨论的这些问题是渔,我什么都授了,大家各取所需。

这里其实有两个问题:一,以什么方式将数据交付给业务层?二,交付什么样的数据给业务层?

iOS开发领域有很多对象间数据的传递方式,我看到的大多数App在网络层所采用的方案主要集中于这三种:Delegate,Notification,Block。KVO和Target-Action我目前还没有看到有使用的。

目前我知道边锋主要是采用的block,大智慧主要采用的是Notification,安居客早期以Block为主,后面改成了以Delegate为主,阿里没发现有通过Notification来做数据传递的地方(可能有),Delegate、Block以及target-action都有,阿里iOSApp网络层的作者说这是为了方便业务层选择自己合适的方法去使用。这里大家都是各显神通,每次我看到这部分的时候,我都喜欢问作者为什么采用这种交互方案,但很少有作者能够说出个条条框框来。

然而在我这边,我的意见是以Delegate为主,Notification为辅。原因如下:

尽可能减少跨层数据交流的可能,限制耦合

什么叫跨层数据交流?就是某一层(或模块)跟另外的与之没有直接对接关系的层(或模块)产生了数据交换。为什么这种情况不好?严格来说应该是大部分情况都不好,有的时候跨层数据交流确实也是一种需求。之所以说不好的地方在于,它会导致代码混乱,破坏模块的封装性。我们在做分层架构的目的其中之一就在于下层对上层有一次抽象,让上层可以不必关心下层细节而执行自己的业务。

那么什么情况跨层数据交流会成为需求?在网络层这边,信号从2G变成3G变成4G变成Wi-Fi,这个是跨层数据交流的其中一个需求。不过其他的跨层数据交流需求我暂时也想不到了,哈哈,应该也就这一个吧。

那么Notification也不是完全不能使用,当需求要求跨层时,我们就可以使用Notification,比如前面提到的网络条件切换,而且这个需求也是需要满足一对多的。

所以,为了符合前面所说的这些要求,使用Delegate能够很好地避免跨层访问,同时限制了响应代码的形式,相比Notification而言有更好的可维护性。

然后我们顺便来说说为什么尽量不要用block

1.block很难追踪,难以维护

我们在调试的时候经常会单步追踪到某一个地方之后,发现尼玛这里有个block,如果想知道这个block里面都做了些什么事情,这时候就比较蛋疼了。

block会给内部所有的对象引用计数加一,这一方面会带来潜在的retaincycle,不过我们可以通过WeakSelf的手段解决。另一方面比较重要就是,它会延长对象的生命周期。

在网络回调中使用block,是block导致对象生命周期被延长的其中一个场合,当ViewController从window中卸下时,如果尚有请求带着block在外面飞,然后block里面引用了ViewController(这种场合非常常见),那么ViewController是不能被及时回收的,即便你已经取消了请求,那也还是必须得等到请求着陆之后才能被回收。

然而使用delegate就不会有这样的问题,delegate是弱引用,哪怕请求仍然在外面飞,,ViewController还是能够及时被回收的,回收之后指针自动被置为了nil,无伤大雅。

所以平时尽量不要滥用block,尤其是在网络层这里。

3.统一回调方法,便于调试和维护

前面讲的是跨层问题,区分了Delegate和Notification,顺带谈了一下Block。然后现在谈到的这个情况,就是另一个采用Block方案不是很合适的情况。首先,Block本身无好坏对错之分,只有合适不合适。在这一节要讲的情况里,Block无法做到回调方法的统一,调试和维护的时候也很难在调用栈上显示出来,找的时候会很蛋疼。

然后我看到大部分App里,当业务工程师写代码写到这边的时候,也意识到了这个问题。因此他们会在block里面写个一句话的方法接收参数,然后做转发,然后就可以把这个方法放在其他地方了,绕过了Block的回调着陆点不统一的情况。比如这样:

[APIcallApiWithParam:paramsuccessed:^(Response*response){[selfsuccessedWithResponse:response];}failed:^(Request*request,NSError*error){[selffailedWithRequest:requesterror:error];}];这实质上跟使用Delegate的手段没有什么区别,只是绕了一下,不过还是没有解决统一回调方法的问题,因为block里面写的方法名字可能在不同的ViewController对象中都会不一样,毕竟业务工程师也是很多人,各人有各人的想法。所以架构师在这边不要贪图方便,还是使用delegate的手段吧,业务工程师那边就能不用那么绕了。Block是目前大部分第三方网络库都采用的方式,因为在发送请求的那一部分,使用Block能够比较简洁,因此在请求那一层是没有问题的,只是在交换数据之后,还是转变成delegate比较好,比如AFNetworking里面:

[AFNetworkingAPIcallApiWithParam:self.paramsuccessed:^(Response*response){if([self.delegaterespondsToSelector:@selector(successWithResponse:)]){[self.delegatesuccessedWithResponse:response];}}failed:^(Request*request,NSError*error){if([self.delegaterespondsToSelector:@selector(failedWithResponse:)]){[selffailedWithRequest:requesterror:error];}}];这样在业务方这边回调函数就能够比较统一,便于维护。

综上,对于以什么方式将数据交付给业务层?这个问题的回答是这样:

尽可能通过Delegate的回调方式交付数据,这样可以避免不必要的跨层访问。当出现跨层访问的需求时(比如信号类型切换),通过Notification的方式交付数据。正常情况下应该是避免使用Block的。

交付什么样的数据给业务层?

我见过非常多的App的网络层在拿到JSON数据之后,会将数据转变成对应的对象原型。注意,我这里指的不是NSDictionary,而是类似Item这样的对象。这种做法是能够提高后续操作代码的可读性的。在比较直觉的思路里面,是需要这部分转化过程的,但这部分转化过程的成本是很大的,主要成本在于:

其实我们的理想情况是希望API的数据下发之后就能够直接被View所展示。首先要说的是,这种情况非常少。另外,这种做法使得View和API联系紧密,也是我们不希望发生的。

在设计安居客的网络层数据交付这部分时,我添加了reformer(名字而已,叫什么都好)这个对象用于封装数据转化的逻辑,这个对象是一个独立对象,事实上,它是作为Adaptor模式存在的。我们可以这么理解:想象一下我们洗澡时候使用的莲蓬头,水管里出来的水是API下发的原始数据。reformer就是莲蓬头上的不同水流挡板,需要什么模式,就拨到什么模式。

在实际使用时,代码观感是这样的:

总结一下,reformer事实上是把转化的代码封装之后再从主体业务中拆分了出来,拆分出来之后不光降低了原有业务的复杂度,更重要的是,它提高了数据交付的灵活性。另外,由于Controller负责调度Manager和View,因此它是知道Manager和View之间的关系的,Controller知道了这个关系之后,就有了充要条件来为不同的View选择不同的Reformer,并用这个Reformer去改造Mananger的数据,然后ViewController获得了经过reformer处理过的数据之后,就可以直接交付给view去使用。Controller因此得到瘦身,负责业务数据转化的这部分代码也不用写在Controller里面,提高了可维护性。

所以reformer机制能够带来以下好处:

在不使用特定对象表征数据的情况下,如何保持数据可读性?

不使用对象来表征数据的时候,事实上就是使用NSDictionary的时候。事实上,这个问题就是,如何在NSDictionary表征数据的情况下保持良好的可读性?

苹果已经给出了非常好的做法,用固定字符串做key,比如你在接收到KeyBoardWillShow的Notification时,带了一个userInfo,他的key就都是类似UIKeyboardAnimationCurveUserInfoKey这样的,所以我们采用这样的方案来维持可读性。下面我举一个例子:

THE END
1.全屋WiFi覆盖方案大比拼,选对更省心全屋WiFi覆盖主要有三种方案:AC+AP、Mesh和FTTR。每种方案都有其独特的优缺点,下面我们来详细了解一下。 1 AC+AP组网 这种方式需要在全屋铺设网线,并在弱电箱中安装AC+POE+路由器的一体机。每个房间的网线连接到AP,再将AP安装在网口86底盒上,通过网线供电。AC负责管理整个网络,设备连接WiFi后可以在各https://mbd.baidu.com/newspage/data/dtlandingsuper?nid=dt_4450577737245841745
2.2013年“三下乡”活动---调研活动总方案 为学习宣传党的十八大精神和习近平总书记五四重要讲话精神,引导广大青年学生深刻理解“中国梦”的广泛内涵,进一步激发广大青年学生投身中原经济区建设、促进中原崛起河南振兴的责任感和积极性,我院“新乡城市文明”调研服务队以学习宣传党的十八大精神和开展“我的中国梦”教育实践活动为契机,以引导青https://www.htu.edu.cn/math/2013/0924/c1386a22890/page.htm
3.观焦点:创业时代创业时代省市场监管局召开“智慧监管”三年行动方案专题研讨会 2023-06-06 当前速讯:治理“黑飞”“乱飞” 我国首项民用无人机国家标准发布 2023-06-06 金汇得手:黄金大幅震荡 1955日内多空分水 2023-06-06 环球看热讯:年金险趸交好还是期交好?作用是什么? 2023-06-06 2亿元!财政部紧急下达 全球微速讯 2023http://wap.022net.com/xinwen/2023/0606/109000.html
4.2024最全澳洲留学生买房攻略(条件+买房流程+贷款+印花税越来越多的中国留学生选择到澳洲留学,澳洲留学生中,有相当一部分同学有移民打算。很多人为了有个长期稳定的居住环境都会选择在澳洲买房,特别是家庭套件还比较好的家庭。毕竟在澳洲租房子的租金也是不便宜的,长期下来还不如自己买套房子划算,在澳洲买房不仅可以节省房租https://www.extrabux.cn/chs/guide/6798280
5.TowardsDataScience博客中文翻译2019(三百四十三)这段经历完全值得,每天都在发现或深入一些东西,扩展我的知识,实践麻省理工学院的座右铭’头脑和手**'***(Mens et Manus)**因为不仅仅是听或参加一个班,做出改变的最好方式是,我们需要用我们的头脑和手来构建实际的解决方案,以产生更大的影响,而一种方法就是使用深层技术。 PShttps://blog.csdn.net/wizardforcel/article/details/142581321
6.新房O2O平台大PK,哪种模式能够真正解决购房需求?第一,平安好房推出好房宝,这是一款更货币基金挂钩的理财产品,购房人将资金存入好房宝,除了能够获得货币基金收益外,在一定时间内通过平安好房认购新房可以获得额外的房积金收益。这种方式既为平安好房自己积累了大量的买房潜在客户,同时还能让自己在房产金融上获得更大的发展。 https://www.tmtpost.com/1028858.html
7.新房装修室内空气检测标准选哪种最适用?科普之窗新房装修好之后,大家都知道不能立即入住,因为很多装修材料和新家具甲醛等有害气体,想要安全入住,就必须对室内空气进行检测治理! 那么,新房装修室内空气检测的标准是什么?选哪种最适用? 我国涉及到室内空气评价的标准有两个: ①GB 50325-2020《民用建筑工程室内环境污染控制规范》,以下简称GB 50325。 http://yipingcn.com/?id=1560
8.什么颜色的窗帘遮光效果好常见窗帘材质哪种好窗帘在家装中成了不可缺的材料之一,有些消费者购买窗帘的时候只看它的花色和款式,却忽略了它的材质,在购买窗帘时要什么颜色的窗帘遮光效果好,这样可以更好的帮助我们选购质量好的窗帘,下面小编为大家介绍常见窗帘材质哪种好。 一、什么颜色的窗帘遮光 https://www.qizuang.com/gonglue/chuanglian/42677.html
9.冬季减肥瘦身最快的方法冬季哪种减肥方法最好→MAIGOO知识爱美之心人皆有之,冬天也不要轻易放纵自己,接受自己身上的肉肉,其实冬季减肥效果会更明显。冬季那种减肥方法最好?冬季减肥不仅要在饮食、作息上注意,做一些合适的运动也是不错的,当然不同人群减肥方法也不一样。 目录 冬季减肥效果 冬季减肥食谱 冬季减肥吃法https://www.maigoo.com/best/2611.html
10.汽车系毕业论文(精选6篇)3.您做过以下哪种学生干部(以最高级别为准)()具体职位___ A.校学生会B.系学生会C.班干部D.协会E.无 4您毕业后是否继续从事汽车行业() A.是B.否C.不确定 5.假如您家里人不想您在工资不高的4S店实习,你将作出怎么样的选择?() A.坚守岗位B.回家做C.和朋友创业D.跳槽其他企业 6https://www.360wenmi.com/f/filedbocmrd3.html
11.www.szfan.com/mokaka26999.html如果想让你的财富保值增值,赶紧与我们联系吧。请注明家庭成员数、收入情况、财务状况、理财目标等,最重要的是别忘了写上你的联系电话。 当地时间15日晚,美国国务卿蒂勒森抵达日本首都东京,开始了上任之后的首次亚洲访问之行。根据美国国务院公布的行程,随后,蒂勒森17日到达韩国,18日访问中国。-——。 http://www.szfan.com/mokaka26999.html
12.“学习之星”百科知识竞赛活动方案14篇(全文)“学习之星”百科知识竞赛活动方案 第3篇 由中国电力企业联合会主办, 中国知网承办的“信用电力”网络知识竞赛活动, 于近期圆满落下帷幕。此次活动共评选出个人奖977名, 其中特等奖2名、一等奖25名、二等奖100名、三等奖300名、鼓励奖550名。 此次“信用电力”网络知识竞赛活动自8月15日开始至10月25日结束, 为https://www.99xueshu.com/w/filef5vg1b80.html
13.橱柜台面哪种材质最好?6种台面材质全面对比,四种方案推荐给你市面上橱柜台面的材质主要分6大类:石英石、天然石、岩板、不锈钢、木台面、亚克力等,虽然说不同类型的台面看起来都存在着很大的差异,但是从选购上真的没有你想的那么简单,往往在现实生活中暗藏着很多的选购技巧,不同的台面材质有着各自的优缺点,而且面对的用户群体也是不一样的,所以说让很多普通老百姓在新房装修https://view.inews.qq.com/k/20231204A07MSA00?no-redirect=1&web_channel=wap&openApp=false