一个App,最核心的就是数据,而数据的主要来源就是API。算法
设计签名:对每一个客户端,Android、iOS、WeChat,分 别分配一个AppKey和AppSecret。须要调⽤用API时,将AppKey加⼊请求参数列表,并将AppSecret 和全部参数一块儿,根据某种签名算法生成一个签名字符串,而后调用API时把该签名字符串也一块儿带上。服务端接收到这个请求时验证AppKey和AppSecret和签名字符串是否一致, 若一致则请求是安全的.每一个端都有一个Key,也⽅便不一样端的标识和统计。为了防止AppSecret被别人获取,这个AppSecret通常写死在代码⾥面。另外,签名算法也须要有必定的复杂度,不能轻易被别人破解,最好是采⽤本身规定的一套签名算法,⽽而不是采用外部公开的签名算法。另外,在参数列列表中再加⼊一个时间戳,还能够防止部分重放攻击 。编程
采用HTTPS, HTTPS由于添加了SSL安全协议,自动对请求数据进行了压缩加密,在必定程度上能够防止监听、劫持、防止重发,主要就是防止中间人攻击。
为了安全考虑,建议对SSL证书进行校验,包括签名CA是否合法,域名是否匹配、是否是自签名证书、证书是否过时等。api
每一个技术团队通常都会有一份接口协议文档,包括对对每一个接口的描述、入参、输出结果等。但通常并不严谨,不少地方没有赞成标准,从而容易出现不少坑。有一份标准且严格执行的接口协议很是重要。
协议的内容除了规定每一个接口中每一个数据具体的数据类型,还须要规定一套共用的数据字典,以及其余须要统必定义的信息,好比签名算法等。缓存
接口变更会致使旧版本App出错,并且变更不必定是修改了接口自己,有多是增长了一种新的数据结构,客户端旧版本解析不了,从而就致使出错。
为了解决接口的兼容性问题,须要作好接口版本控制。实现:
1.每一个接口有各自的版本,通常为接口添加个version参数
2.整个接口系统有统一的版本,通常在URL中添加版本号,好比http://api.domain.com/v2
平时小版本更新,就采用第一种方式, 根据不一样版本号作不一样分支的处理;大版本采用第二种。(跟旧版本相对独立
)
太旧的版本提醒用户强制升级或者普通升级。安全
高内聚、低耦合
)数据管理、数据加工、数据展现,三层架构:数据层
、业务层
、展现层
网络
1>业务层向数据层请求数据;
2>数据层检查缓存中有没有请求须要的数据;
3>若是有缓存直接返回缓存数据;
4>若是没有缓存,则从网络API获取数据,并将数据加入缓存,而后返回数据。
调用API 时,还要判断网络状态,根据不一样状态作不一样处理。若是网络不可用,就无需发起请求。无网络可用时,也要区分是WIFI仍是移动网络。链接移动网络时,通常要限制比较耗流量的请求。
获取分页数据时, 能够将下一页的数据预先请求、
缓存策略:对于获取数据的接口设置缓存。
数据层与外部交互:提供对外开放的数据接口。参数分为两类:系统参数和业务参数,像appKey、version、sign、time这些属于系统参数,而currentPage,或usderName的类则属于业务参数。
数据层开发的接口参数只须要包含业务参数就能够了,业务层并不须要关心系统参数是什么,系统参数在内部封装API时就已经指定了。数据结构
从数据层获取数据,而后通过业务逻辑处理后转化成展现层须要的数据。(参数的有效性检查,注册成功后自动登陆)
业务层交付给展现层的数据也是经过接口的方式,不一样于数据层交付给业务层的是,给展现层的数据应该是经过异步回调返回的。由于获取数据是一个比较耗时的任务,经过异步回调才不会阻塞UI主线程。架构
关心数据如何展现:
界面布局、屏幕适配、图片资源、文本资源、颜色资源等等、
保持高质量代码:
1>保持规范性:定义好开发规范,包括书写规范、命名规范、注释规范等,并按照规范严格执行;
2>保持单一性:布局就只作布局,内容就是只作内容,各自分离好,每一个方法、每一个类,也只作一件事情;(保持单一性是减低耦合度的关键标准,界面的单一就是要保持界面上每一个维度作好分离,从界面布局到数据获取,数据检查,数据展现)。
3>保持简洁性:保持代码和结构的简洁,每一个方法,每一个类,每一个包,每一个文件,都不要塞太多代码或资源,感受多了就应该拆分。
代码混乱的问题必须严格执行开发规范。mvc
MVC 架构问题:
繁重的UI ,啰嗦业务逻辑,难受的用户代理,很长的网络层,内部方法,app
解决办法:
面向协议,View和Model彻底解耦,Controller层不显示网络请求数据的过程,只要遵循协议就能拿到数据
V层UI改变,通知P层,P层更新数据通知M层,M层拿到新数据通知P层,P层通知V层UI改变。
MVP 优缺点:
①模型与视图彻底分离,咱们能够修改视图而不影响模型
②能够更高效的使用模型,由于全部的交互都发生在一个地方,Presenter内部
③咱们能够将一个Presenter用于多个视图,而不须要改变Presenter的逻辑。这个特性很是的有用,由于视图的变化老是比模型的变化频繁。
④若是咱们把逻辑放在Presenter中,那么咱们就能够脱离用户接口来测试这些逻辑(单元测试)
KVO双向绑定
ViewModel做为枢纽,沟通View和Model之间的关系。
- (void)setWithViewModel:(MVVMViewModel *)vm { self.vm = vm; //KVO [self.vm addObserver:self forKeyPath:@"nameStr" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil]; self.label.text = vm.nameStr; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change: (NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ if ([keyPath isEqualToString:@"nameStr"]&&[change objectForKey:NSKeyValueChangeNewKey]) { NSNumber *new = [change objectForKey:NSKeyValueChangeNewKey]; self.label.text = [NSString stringWithFormat:@"%@",new]; } } -(void)mvvmClickChangModel{ [self.vm clickChangeName]; } //MVVMModel #import "MVVMViewModel.h" @implementation MVVMViewModel -(void)setWithModel:(MVVMModel *)model{ self.model = model; self.nameStr = model.name; } -(void)clickChangeName{ self.model.name = [NSString stringWithFormat:@"name%d",arc4random()%10]; self.nameStr = self.model.name; NSLog(@"%@",self.nameStr); } @end