ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:56.27KB ,
资源ID:22684812      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/22684812.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(iOS网络层架构设计分享Word下载.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

iOS网络层架构设计分享Word下载.docx

1、6. admin_id529ecfd647. code:错误码,可以记录下来快速定位接口错误原因,可以定义一套错误码,比如200正常,1重新登录. msg:接口文案提示,包括错误提示,用来直接显示给用户,所以这一套错误提示就不能是什么一串英文错误了 data:需要返回的数据,可以是字典,可以是数组接口帮我们定义了code和msg,是不是我们就不需要做错误处理了?当然不是,服务端的错误逻辑毕竟是简单的,具体到data里面的数据处理可能还有错误,所以错误的处理是必不可少的,下面会单独对错误处理做介绍2.网络请求参数上传方式统一这里一般都能做到,也有额外的,比如我们的一个服务器接口做的比较早,当时P

2、OST接口使用的就不规范,普通的应用信息channelID、device_id使用的是拼接在字符串后面的方式,而真正的请求参数则需要转成json放在一个字段里面传递,就是接口GET、POST并存的方式,造成网络层需要做特殊处理所以说标准的GET、POST请求方式是很有必要的3.关于Null类型大家都知道Null类型在iOS里面是很特殊的,我的建议是放在客户端来做,原因有很多:1)接口的规范定义并不是每个公司都是从一开始就能定义好的,老接口如果要把Null字段去掉的改动非常大2)客户端用过一个接口过滤也可以解决,一劳永逸,不用再担心因为某天接口的问题出现崩溃,而且通过一些Model的第三方库也可

3、以很好的解决这个问题。这里不得说下swift的类型检测真是太方便了,之前一个项目用swift写的,代码规范一点,根本不会出现因为参数类型问题引起崩溃多服务器多环境设置这部分基本上是照搬casa大神的设计,这里我延伸了一个多环境的设计,小的项目一般都是一个服务器,但是像淘宝之类的项目一个服务器显然是不可能的,多个服务器的设计还是非常普遍的。根据一个枚举变量通过ServerFactory单例生成获取对应的服务器配置1.服务器环境标准的APP是有4个环境的,开发、测试、预发、正式,特别是服务器的代码,不能说所有的代码更改都在正式环境下,应该从开发-测试-预发-正式做代码的更新,开发就是新需求和优化的

4、时候的更改,测试就是提交给测试人员后的更改,这个时候更改是在一个新的分支上,完成后要和合并到测试分支上并合并到开发分支上,预发这时候的变动就比较小了,一般会在测试人员完成后发布给全公司的人来测试,有问题了才会更改,更改后同样合并到开发分支,正式则是线上发布版本的紧急BUG修复,修改完后同样合并到开发分支上。所以开发分支是一直都是最新的。在此基础上可能会有其他的环境,比如hotfix环境,自定义的h5/后台本地调试的环境。客户端同样存在这些环境,并且要提供切换的入口。在我的demo中提供了两套设置,一套是第一次安装应用的初始化环境(宏定义),另外是手动切换环境的设置(枚举EnvironmentT

5、ype)。这里有一个比较绕的逻辑,宏定义的正式环境设置高于手动切换环境设置,手动切换环境设置高于宏定义其他环境1. /宏定义环境设置2. #if!definedYA_BUILD_FOR_DEVELOP&YA_BUILD_FOR_TESTYA_BUILD_FOR_RELEASEYA_BUILD_FOR_PRERELEASE3. #define4. /#define5. /#define6. /#defineYA_BUILD_FOR_HOTFIX7. /#define/该环境的优先级最高8. #endif9. /手动环境切换设置10. #ifdef11. /优先宏定义正式环境12. self.en

6、vironmentType=EnvironmentTypeRelease;13. #else14. /手动切换环境后会把设置保存15. NSNumber*typeNSUserDefaultsstandardUserDefaultsobjectForKey:environmentType;16. if(type)17. /优先读取手动切换设置18. self.environmentType(EnvironmentType)typeintegerValue;19. else20. #ifdef21. EnvironmentTypeDevelop;22. #elif23. EnvironmentTy

7、peTest;24. 25. EnvironmentTypePreRelease;26. 27. EnvironmentTypeHotFix;28. #endif29. 30. #endif所以当宏定义正式环境存在的时候是不能手动切换环境的,用于普通用户的发布版本,但是其他宏定义环境时是可以切换到正式环境的。半个坑另外手动切换自定义的环境是在基类中实现的,而其他的环境配置是在协议中实现的,这就和其他环境地址的配置不统一了。可以这样理解,这里的基类是为了提供已返回值,协议是为了返回值的灵活,既然自定义环境的地址配置不需要灵活性,自然是放在基类好。思路是大方向,实现是灵活的,如果非要放在协议中实现

8、也无不可以,无非是赋值粘贴几次一样的代码,但是一模一样的代码是我最不喜欢看到的,所以就放在基类了。如果有更好的解决方案欢迎提供2.扩展性model提供的是高扩展性,针对不同的不服务器添加更多的配置,比如加密方法,比如数据解析方法.前面提到了,统一的规范有的时候不是一时半会就能做好的,兼容就成了需求,这个时候不同服务器的个性化设置就可以在协议中声明并实现了,基类提供返回值就好网络层数据传递(请求和返回)网络层数据传递Client、BaseEngine/DataEngine、RequestDataModel数据传递网络请求的发生在我理解中分两步,一步是数据的整理,一步是生成Request并发起请求

9、,基于这个思想我拆分出了Client和Engine,然后又把URLRequestGenerator从Client中拆分出来,Engine拆分出了下层的BaseEngine和面向不同业务的DataEngine,而从BaseEngine到Client,再到URLRequestGenerator是要做数据传递的,请求参数和返回参数,所以又有了RequestDataModelRequestDataModel1. interfaceYAAPIBaseRequestDataModelNSObject2. /*3. *网络请求参数4. */5. property(nonatomic,strong)NSStr

10、ing*apiMethodPath;/网络请求地址6. propertyassign)YAServiceTypeserviceType;/服务器标识7. propertyNSDictionary*parameters;/请求参数8. propertyYAAPIManagerRequestTyperequestType;/网络请求方式9. propertycopy)CompletionDataBlockresponseBlock;/请求着陆回调10. /upload11. /file12. property*dataFilePath;13. property*dataName;14. prope

11、rty*fileName;15. property*mimeType;16. /download17. /18. /progressBlock19. propertyProgressBlockuploadProgressBlock;20. propertydownloadProgressBlock;21. end可以看出来RequestDataModel属性都是网络请求发起和返回的必要参数,这样做的好处真的是太大了,不知道大家有没有这样的场景:因为请求参数的不同做了好多方法接口暴露出去,最后调起的还是同一个方法,而且一旦方法写的多了,最后连应该调用哪个方法都不知道了。我就遇到过,所以现在我的网

12、络请求调起是这样的:1. /没有回调,没有其他的参数,只有一个dataModel,节省了你所有的方法2. YAAPIClientsharedInstancecallRequestWithRequestModel:dataModel;生成NSURLRequest是这样的:1. NSURLRequest*requestYAAPIURLRequestGeneratorgenerateWithYAAPIRequestWithRequestDataModel:requestModel;可以看到我的demo里面的YAAPIClient类和YAAPIURLRequestGenerator类方法至少,方法少就

13、意味着逻辑简单明了,方便阅读,两个类的代码行数都是120行,120行实现了网络请求的发起和着陆,你能想象吗另外RequestDataModel带来的另外一个好处就是高扩展性,你有没有遇到网络层需要添加删除一个参数导致调用方法修改了,然后很多地方都要修改方法?用RequestDataModel只需要添加删除参数就行了,只需要改方法体,这个改方法体和同时改方法名方法体是完全两个工作量。哈哈,有点卖虎皮膏药的感觉。这个的确是我的得意创新点ClientClient做两个操作,一个是生成NSURLRequest,一个是生成NSURLSessionDataTask并发起,另外还要暴露取消操作给Engine

14、,URLRequestGenerator是生成NSURLRequest,URLRequestGenerator会对dataModel进行加工解析,生成对应服务器的NSURLRequest然后Client通过NSURLRequest生成NSURLSessionDataTaskClient和URLRequestGenerator都是单例1. -(void)callRequestWithRequestModel:(YAAPIBaseRequestDataModel*)requestModel2. NSURLRequest3. generateWithRequestDataModel:AFURLSes

15、sionManager*sessionManagerself.sessionManager;NSURLSessionDataTask*tasksessionManagerdataTaskWithRequest:request7. uploadProgress:requestModel.uploadProgressBlock8. downloadProgress:requestModel.downloadProgressBlock9. completionHandler:(NSURLResponse*_Nonnullresponse,10. id_NullableresponseObject,1

16、1. NSErrorerror)12. 13. /请求着陆14. ;15. taskresume;16. 取消接口参考了casa大神的设计,使用NSNumber *requestID来做task的绑定,就不多做介绍了BaseEngine/DataEngineEngine或者说是APIManager在我的设计中既不是离散的也不是集约的casa大神的理论集约型API调用其实就是所有API的调用只有一个类,然后这个类接收API名字,API参数,以及回调着陆点(可以是target-action,或者block,或者delegate等各种模式的着陆点)作为参数。然后执行类似startRequest这样的

17、方法,它就会去根据这些参数起飞去调用API了,然后获得API数据之后再根据指定的着陆点去着陆。比如这样:1. APIRequeststartRequestWithApiName:itemList.v1params:paramssuccess:selector(success:)fail:selector(fail:target:self;离散型API调用是这样的,一个API对应于一个APIManager,然后这个APIManager只需要提供参数就能起飞,API名字、着陆方式都已经集成入APIManager中。1. propertyItemListAPIManager*itemListAPIM

18、anager;2. /getter3. -(ItemListAPIManager*)itemListAPIManager4. if(_itemListAPIManager=nil)_itemListAPIManagerItemListAPIManagerallocinit;_itemListAPIManager.delegateself;return_itemListAPIManager;10. 使用的时候就这么写:12. self.itemListAPIManagerloadDataWithParams:params;各自的优点就不说了,但是由此延伸出几个问题:1.参数的传递使用字典对于网络

19、层来说是不可知的,而且业务层需要去关注接口字段的变化,其实是没有必要的2.离散型API会造成Manager大爆炸3.集约型会造成取消操作不方便4.取消操作并不是每个接口必须的,如果写成部分离散的部分集约的,代码的整体结构.我是个有强迫症的人,看不得这样的代码所以我的设计主要就解决了上面的这些问题1.面向业务层的DataEngine只传递必要的参数进来,不使用字典,比如SearchDataEngine2. +(YABaseDataEngine*)control:(NSObject*)control3. searchKey:(NSString*)searchKey4. complete:(Comp

20、letionDataBlock)responseBlock;5. endcontrol暂时先不管,是做自动取消的,后面再介绍。searchKey就是搜索的关键字在调用的时候就是这样1. self.searchDataEngineSearchDataEnginecontrol:selfsearchKey:关键字complete:(iddata,*error)(error)NSLog(%,error.localizedDescription);,data);7. ;2.我按业务层来划分DataEngine,比如BBSDataEngine、ShopDataEngine、UserInforDataEn

21、gine.每个DataEngine里面包含各自业务的所有网络请求接口,这样就不会出现DataEngine大爆炸,像我们的项目有300多个接口,拆分后有十几个DataEngine,如果使用离散型API设计,那画面太美我不敢看?3.BaseEngine提供取消操作每个接口生成一个BaseEngine实例,持有Client返回的requestID,所以就可以做取消操作,简单的使用场景1. #importViewController.h2. #importSearchDataEngine.h3. interfaceViewController()4. propertyYABaseDataEngine*

22、searchDataEngine;6. implementation7. -(void)viewDidLoadsuperviewDidLoad;/Doanyadditionalsetupafterloadingtheview,typicallyfromanib.self.searchDataEnginecancelRequest;self.searchDataEngine16. 18. 19. end4.返回的YABaseDataEngine实例ViewController不是必须持有的,当有需要取消操作的时候再去持有就行了这样的设计就集成了集约型和离散型的有点,又解决了集约型和离散型的缺点网

23、络请求怎么自动取消当一个页面的请求正在天上飞的时候,用户等了好久不耐烦了,小手点了个back,然后ViewController被pop被回收。此时请求的着陆点就没了。这是很危险的情况,着陆点要是没了,就很容易crash的。casa大神说在BaseDataEngine的dealloc里面做取消网络请求操作,我也是这样想的,但是casa大神说要把BaseDataEngine绑定给ViewController,当ViewController销毁时BaseDataEngine也就跟着销毁了,这样我也是同意的,但是要让我不管什么情况都要给ViewController添加BaseDataEngine变量来保存BaseDataEngine这是我万万不能接受的,而且有的ViewController会发起两三种网络请求,难道要我添加两三个变量?代码入侵太大,所以这里偷偷使用了一个巧,使用了runtime,给ViewController添加一个字典,来保存requestID和BaseDataEngine,这样对于ViewController来说就不是必须要写变量来持有BaseDataEngine了,所以就出现了上面的DataEngine里面要把control传递进来的样子在发起请求的时候进行绑定

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1