iOS 组件化开发笔记

382 阅读4分钟

一、背景

当我们的项目越来越复杂庞大,开发团队成员也不断增加,原先的项目架构在维护过程中效率越来越低,这时候需要提升开发效率,减少维护的成本,这时候就应该考虑重构项目,组件化开发是一个不错的选择。

二、组件化开发介绍

组件化开发,顾名思义,就是以组件的形式,按照业务功能等方式对我们现有的庞大的工程进行拆分,团队的不同成员负责各自的功能模块,且拆分出来的组件可以独立运行,互不干涉,最终将开发好的组件组合到宿主工程中的一套完整的解决方案。

组件化开发不仅仅是对项目进行重构,也给开发团队进行了划分,每个人的分工更加明确,对技术团队来讲也是一种重构。

组件化开发的优势

  • 模块间解耦
  • 提高模块的复用率
  • 提升团队开发效率
  • 方便单元测试
  • 方便后期维护

组件化的实现思路

项目构建形式

每个组件以Pod库的形式存在,利用CocoaPods的方式安装各个组件,Git管理组件的版本,如下图所示:

image.png

iOS 组件化开发架构设计

组件化分层一:

image.png

组件化分层二:

image.png

注意点: 业务模块横向之间不能依赖,只能上层对下层依赖,项目公共代码资源下沉,横向的依赖也最好下沉。

关于解耦的一些优秀框架

CTMediator

CTMediator 利用runtime调用target-action的方式。在iOS中调用方法本质就是发送消息,消息包括 接受者消息主体

在 iOS中可以直接调用某个对象的消息方式有两种: 一种是performSelector:withObject; 再一种就是NSInvocation。 第一种方式比较简单,能完成简单的调用。但是对于>2个的参数或者有返回值的处理,那performSelector:withObject就显得有点有心无力了,那么在这种情况下,我们就可以使用NSInvocation来进行这些相对复杂的操作。

CTMediator主要用的就是这两种方式: 部分代码摘录如下:

NSMethodSignature* methodSig = [target methodSignatureForSelector:action];
if(methodSig == nil) {
    return nil;
}
const char* retType = [methodSig methodReturnType];

·····

if (strcmp(retType, @encode(NSUInteger)) == 0) {
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
    [invocation setArgument:&params atIndex:2];
    [invocation setSelector:action];
    [invocation setTarget:target];
    [invocation invoke];
    NSUInteger result = 0;
    [invocation getReturnValue:&result];
    return @(result);
}
return [target performSelector:action withObject:params];

MLSOAppDelegate

MLSOAppDelegate : 通过runtime的事件转发,将代理协议中的方法进行动态转发,在自己代码中没有实现所有代理方法。

FRDModuleManager

FRDModuleManager : 实现代理中所有方法,简单的将AppDelegate的单路代理改成多路代理。

BeeHive

BeeHive: 用于iOS应用开发的App模块化编程的框架实现方案,吸收了Spring框架Service的理念来实现模块间的API耦合,就是一个中间层。

三、组件化开发的解决方案

网友的解决方案一:

基于 MLSOAppDelegate 进行优化,增加 BeeHive 的优点(支持顺序设定、异步加载),支持相对顺序+CTMediator进行优化(增加Target预检测),业务层增加部分抽象。

四、组件化实践

Cocoapods 介绍

image.png

1、利用pod命令创建模块

pod lib create xxxModule

在终端输入该命令之后,会出现一些提示需要填写的内容,按照自己的需求填写,然后回车就可以了。 最终在本地生成一个文件夹,目录大概如下所示(以上过程都是pod帮我们完成的):

image.png

2、编写模块

我们编写代码的地方就在Classes文件夹下面。

3、安装并使用模块

等编写完成之后,进入如图所示Example目录,执行pod install

image.png

可以看到编写的Module已经被添加到了该Example的Pods目录下.

4、组件的第三方和本地依赖处理

当我们编写组件的时候,不可避免地要引用到一些第三方的组件,那么怎么解决三方组件的依赖问题呢?

如下是三方依赖添加的位置: image.png

本地组件依赖的添加在Podfile中添加,指定路径,如下图所示:

image.png

5、组件化资源文件的加载问题

当我们把上述工作准备好,运行的时候会发现资源文件未加载出来,那接下来就解决该问题:

先将图片资源放到Module目录下的Assets文件夹下面,接下来资源加载的方式也需要修改一下:

image.png

还需要修改如下所示的文件:

image.png

回到刚刚的工程下,重新执行pod install,然后就可以加载出来了。

6、组件化CTMediator解耦通讯
7、组件化BeeHive解耦

参考资料

BeeHive框架全面解析——iOS开发主流方案比较

iOS组件化开发从开始到完整总结