iOS架构
公司项目采用了这个架构开发。

讲iOS架构不得不说到工程目录,我的工程目录由business、common、local_library、library、third、other六部分组成。
business主要由iOS业务开发工程师来开发,大模块界定清晰,比如登录模块、首页模块等等。
common包含跟业务关联很大的一系列公共代码,比如数据库处理、反射等等。
local_library包含了跟业务无关联并可抽离成.a文件或者.framework文件的一系列公共代码。
library为GitHub上优秀的第三方开源代码,比如AFNetworking、SDWebImage等等。
third为其他厂封装的调用库,比如微信、高德等等。
other为一些资源文件和配置信息。
-------------------------------我是分割线-------------------------------
先看business,business中首当其冲的是AppDelegate,这个强奸了无数iOS开发者的启动类。这个类中关键的方法有:
didFinishLaunchingWithOptions、applicationDidBecomeActive、openURL。其他方法不是那么重要,忽略。
我在didFinishLaunchingWithOptions中放置了以下信息:
初始化TabBar
状态栏、底部栏配置
推送配置
分享配置
加载配置
定位配置
网络配置
引导页配置
广告页配置
applicationDidBecomeActive中放置了以下信息:
更新用户token
版本检测
openURL中放置了以下信息:
分享回调处理
组件化处理
然后就是root这个,root中的controller包含了tabBar、navigation、web。由之前的信息得知,AppDelegate中初始化tabBar。
我在tabBar中放置了以下信息:
初始化了各个主要的navigation
自定义tabBar设置
导航栏设置
推送回调统一处理
我在navigation中放置了以下信息:
系统手势返回处理
自定义返回按钮处理
web介绍:app中所有的只有一个h5页面的统一处理都在这里完成。而且它还是其他复杂h5交互页面的父类,里面提供了h5进度条提示等服务
-------------------------------我是分割线-------------------------------
然后是business中AppDelegate、root的其他模块,login、main、detail等等。总体来看,大模块下的子模块基本上是按照MVC的方式划分,有些改成了MVVMC的方式。说到MVC、MVVMC或者MVVM等等,其实只是个噱头,不要太执迷于这种流于表面的东西。
刚开始,什么东西都是控制器,一个控制器能够写1,2万行的代码,做java的童鞋会更深有体会。后来发现1,2万行的代码不好跟,而且代码冗余、复用性差,就拆离出了View和Model这层,变成了所谓的MVC。
MVC,View就是单纯放置自定义视图了,对我来说是这样,放着自定义视图和单元格。而Model这个东西就很有意思了,很多做java的,Model都放着一个从接口返回的数据组装成的包含get、set的类,而我在Model中没有放这些,因为我不敢苟同那种做法,比较low。我在Model放置了delegate、request还有reformer(reformer使用了适配器模式),Model这一层应该是比较纯粹的,和视图没有任何关联。
即便是有了M和V的支持,但是仍然会出现C臃肿的现象,一般来说,一个控制器的代码行数要控制在1000行以内,我的工程里面也是这样做的。所以这个时候需要再分离出一层viewmodel,viewmodel看似是视图和模式的关联,但其中和控制器的关联还是有的,而且还是强业务关联,比如说code,这个是短信业务逻辑,适用于工程中所有集成了短信业务的处理;而face则是封装了头像的交互逻辑;keyboardmodel封装了界面与已定义键盘之间的交互逻辑等等。
-------------------------------我是分割线-------------------------------
接下来说说控制器或者视图内的代码分组,要严格按照这个分组,如果有人没有按照这个分组写代码,我会叼人的。
#pragma mark - test 存放测试信息
//临时的测试信息,都放在这里,便于快速调试。
#pragma mark - push or pop 控制器
//控制器跳转处理
#pragma mark - request 请求信息
//请求处理
#pragma mark - public method 公共方法
//提供给对外调用的公共方法,一般来说,我的控制器是很少有提供给外界调用的方法,在viewmodel中有比较多的公共方法。
#pragma mark - private method 业务无关的尽量弄成category,方便别人调用
//没有暴露给外面调用的方法。
#pragma mark - life cycle 生命周期
//工程的viewDidLoad、viewWillAppear、init、didReceiveMemoryWarning等方法都放在这里
#pragma mark - event response 事件响应包括手势和按钮等
//事件响应,包含手势、按钮、通知等等事件的处理
#pragma mark - delegate 具体到某个delegate,比如UITableViewDelegate
//代理或者数据源
#pragma mark - view layout 子视图的布局
//界面布局
#pragma mark - getters and setters 构造器
//get和set方法
-------------------------------我是分割线-------------------------------
然后说说common,里面包含:constants、component、request、database、notification、location、injection、category、switch
constants,常量业务,包含普通常量的配置类和控制器常量的配置类。
普通常量配置类尽量不要包含太多的常量,对于可独立出来的library里面不要包含普通常量配置类里面的常量。
我放置了以下信息:
iPhone X适配判断
多语言自定义
本地版本号定义
工程颜色样式
工程图片样式
等等,没有太多东西。
控制器常量配置类主要是通过增加枚举常量,将枚举值转成一个个控制器,配合组件化处理,可以减少对控制器的引入。所以一般在我做的控制器中,不会再引入其他的控制器,因为那些控制器都用组件化的方式跳转。
component,组件化的业务处理,将工程中的几乎所有业务控制器的初始化和跳转工作都放在这里处理。
request,请求的业务处理,包含请求常量配置类和服务配置类。
请求常量配置类,我放置了以下信息:
测试与正式的服务器地址
测试与正式的h5地址
测试与正式的图片上传地址
分页常量
一些重要的请求状态码
各个业务请求URI
各个h5请求URI
服务配置类,包含以下信息:
线上线下的请求网址
请求网址拼接
请求参数加密
请求失败统一处理
这个类中放置了以下信息:
NSUserDefaults存储
SQLite存储
SQLite升级配置
多用户存储设计
业务缓存设计
其他文件,如mp3
这个类中放置了以下信息:
通知推送常量
注册唯一标识符
红点处理
定位处理
逆地址处理
经纬度、地址存储
injection,反射业务,在load中配合Aspects使用代码注入,其中运用了IOP和AOP。
这个类中放置了以下信息:
统一处理控制器背景颜色
去掉控制器中膈应的设置
状态栏切换处理
跟踪控制器释放问题
category,类别,分为Foundation类别和UIKit类别,里面封装了各种工具,比如加密。在先前提到的控制器代码分组中,private中有很多方法都可以抽离成category。
switch,环境切换,用到第三方工具,会经常区分正式和测试,使用这个类来区分这两个环境。
-------------------------------我是分割线-------------------------------
share分享页集成
advert广告页集成
sound音效播放集成
keyboard自定义中文键盘集成
introduction引导页集成
alert自定义提示框集成
upload单图或多图上传集成
load转圈圈集成
component组件化,其中规定了iOS应用外通信和应用内通信以及控制器缓存。
network网络
network网络设计,底层还是直接借用AFNetworking。
包含了以下信息:
请求拦截器
请求数据校验
请求本地缓存
网络配置类
服务类
请求类
响应类
日志类
数据格式分类
等等
-------------------------------我是分割线-------------------------------
SVProgressHUD提示框
TZImagePickerController图片选取
AFNetworking网络请求
Aspects方法转换
FMDB数据库
Masonry布局
MBProgressHUD提示框
MJRefresh上下拉刷新
NJKWebViewProgress网页进度条
ReactiveObjC响应式编程
SDWebImage图片请求
other为一些资源文件和配置信息,包含了Assets、Storyboard、Localizable、Info、main、PrefixHeader、Target。
包含了以下信息:
Assets,工程的图片资源都存放在这里。
Storyboard包括启动页和主工程,使用了Masonry布局,就没有用Storyboard了。
Localizable国际化,你需要这个(@"[^"]*[\u4E00-\u9FA5]+[^"\n]*?")\s*正则。
Info除了各种权限说明,还有网络白名单设置。
main函数,程序的最最最先的入口。
PrefixHeader,定义了公共头文件。
Target,包含一个正式的和一个测试的。
-------------------------------我是分割线-------------------------------
注释、规范化、模块化是非常重要的事,不仅有利于团队合作,还可以让后来接手的人快速上手。
每个部分基本都是轻描淡写,但是细细展开,其实都有非常多的内容,在其中可以代入自己的思考,然后一点点完善,祝好运。
-------------------------------我是分割线-------------------------------