学计算机的那个

不是我觉到、悟到,你给不了我,给了也拿不住;只有我觉到、悟到,才有可能做到,能做到的才是我的.

0%

iOS可复用项目框架搭建

入职了一家公司,刚好处于项目启动阶段,花了一周时间搭建了项目框架,现在总结一下。

框架设计目的

软件系统的框架设计跟盖房子搭框架原理相似,根基打牢了,框架搭好了,后续就是往里面填业务逻辑了。框架系统的搭建所遵循的原则如下

  1. DRY即Don’t repeat yourself
  2. Kiss即Keep It Simple,Stupid
  3. 六大设计原则(Solid)

让工程架构更简洁易懂,隐藏复杂的细节提供易用的API

  • 框架设计模式

这里项目采用的MVVM的框架设计模式,因为VM作为中间层,可以适应不同业务层的数据逻辑处理,从而提高Controller作为View的复用率。

ViewModel其实是View的数据层的影子,它的神奇之处在于这个影子是可以被改变然后映射到实体上。这个过程中ViewModel抽象出UI的数据,然后将这些与UI上的属性进行绑定

实现

APP业务无关的功能模块进行封装

  1. 常用分类Category

为了提高可复用性,通过将一些通用(Kit、Foundation相关)业务无关的功能封装成私有库,这里用私有Pod来管理,避免开发其他App时重复工作,暂时就封装了两个私有库,一个Kit,一个Foundation,两个库的实现都是借鉴YYCategories里面的功能,因为作者写得实在太好,无法超越….同时将一些常用的与业务无关的宏定义也分别放在了私有库里面了。

  1. 网络层
    公司都会有自己的网络层,集中型或者分散型,目前主流的是借鉴猿题库的YTKNetwork,把每个网络请求实例化,便于定制缓存,请求管理和依赖,这里我借鉴的是网上的一个基于MVVM的网络框架,也是将每个请求实例化,通过代理的方式(没有使用Block捕获对象导致对象延迟释放问题),定义一个请求的基类,基于基类又封装了一个分页的请求基类

  2. 后续会将一些通用的自定义View封装成库

PCH文件

PCH的作用:

  1. 存放一些全局的宏(整个项目中都用得上的宏) 一个用来定义APP相关的主题类(UIColor,UIFont)宏文件,一个第三方参数的宏文件
  2. 用来包含一些全部的头文件(整个项目中都用得上的头文件)
  3. 能自动打开或者关闭日志输出功能

Base基类

继承作为一种强关联的高耦合方式,在开发的时候是要慎用的,一般都是建议使用组合方式进行替换,基于OC的语言特性,可以使用相应的分类实现。(实际中组合(Composition)往往结合接口、委托(delegation)这两种技术手段来解决继承的问题 )

继承是一种is-a的关系,而组合是一种has-a关系

  • BaseViewController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
@interface WSFBaseViewController : UIViewController
/**
* 修改状态栏颜色
*/
@property (nonatomic, assign) UIStatusBarStyle StatusBarStyle;

@property(nonatomic)UIInterfaceOrientationMask supportedOrientationMask;

@property (nonatomic) UITableView * tableView;
@property (nonatomic) UICollectionView * collectionView;

-(void)didInitialized NS_REQUIRES_SUPER;

#pragma mark -- 加载 ViewController
//是否为刷新状态
- (BOOL)isShowReFreshingStatus;
//显示菊花
- (void)showReFreshingViewWithTip:(NSString *)tip;
//关闭菊花
- (void)hiddenReFreshingView;
//显示错误
- (void)showErrorViewWithTip:(NSString *)tip;

#pragma mark - 导航栏

/**
* 是否显示返回按钮,默认情况是YES
*/
@property (nonatomic, assign) BOOL isShowLeftBack;

/**
是否隐藏导航栏
*/
@property (nonatomic, assign) BOOL isHidenNaviBar;
/**
导航栏添加文本按钮

@param titles 文本数组
@param isLeft 是否是左边 非左即右
@param target 目标
@param action 点击方法
@param tags tags数组 回调区分用
*/
- (void)addNavigationItemWithTitles:(NSArray *)titles isLeft:(BOOL)isLeft target:(id)target action:(SEL)action tags:(NSArray *)tags;

/**
导航栏添加图标按钮
@param imageNames 图标数组
@param isLeft 是否是左边 非左即右
@param target 目标
@param action 点击方法
@param tags tags数组 回调区分用
*/
- (void)addNavigationItemWithImageNames:(NSArray *)imageNames isLeft:(BOOL)isLeft target:(id)target action:(SEL)action tags:(NSArray *)tags;

/**
* 默认返回按钮的点击事件,默认是返回,子类可重写
*/
- (void)backBtnClicked;
@end


@interface WSFBaseViewController (WSFSubclassViewController)
- (void)initSubviews NS_REQUIRES_SUPER;
-(void)addConstraint;
-(void)setup
  • LoadPageView

每个页面都会有NoData,网络故障等通用状态显示页面,这里单独封装成一个对象

参考

  1. YTKNetwork学习
  2. iOS项目架构设计
  3. 今日头条:iOS 架构设计杂谈
  4. Demo
  5. Code