基于CTMediator的组件化方案
基于CTMediator的组件化方案
组件化方案:
总的来说做组件化,目前比较成熟的方案有两种:
1、基于CTMediator的组件化方案。
2、是类似于蘑菇街Protocol-Class,目前我所采用的是基于CTMediator的组件化方案,这里着重讲一下他的实现以及开发过程中所遇到的一些问题。
原理:
(1)CTMediator:CTMediator主要采用target-action的方式实现组件间解耦合,本身功能完全独立,不依赖任何组件模块。其原理是通过给组件包装一层wrapper来给外界提供服务,然后调用者通过依赖中间件来使用服务,其中,中间件是通过runtime来调用组件的服务,是真正意义上的解耦,也是该方案最核心的地方。具体实施过程是给组件封装一层target对象来对外提供服务,不会对原来组件造成入侵;然后,通过实现中间件的category来提供服务给调用者,这样使用者只需要依赖中间件,而组件则不需要依赖中间件。本方案主要依赖于CTMediator这个框架,其内部实现在下篇文章着重介绍。
(2)Protocol-Class:通过protocol定义服务接口,组件通过实现该接口来提供接口定义的服务,具体实现就是把protocol和class做一个映射,同时在内存中保存一张映射表,使用的时候,就通过protocol找到对应的class来获取需要的服务。
模块划分:
1、模块划分可根据自身业务以及需求进行划分,这里主要说下我们针对模块做的一个初步划分:
image.png
CTMediator大致步骤:
步骤总结:
第一:添加私有 Pods源
第二:创建 TestA的 Xcode 工程和对应的私有 Repo,并配置其TestA.podspec文件
第三:创建 TestA_Category 的 Xode 工程和对应的私有 Repo,并配置其TestA_Category .podspec文件。
第四:验证两个工程的.podspec文件
第五:准备发版 pod
第六:在TestA_Category 工程Classes文件夹下创建CTMediator+A,在TestA工程创建 Target(一个组件对应一个 Target-Action)
第七:CTMediator组件化
具体实现步骤:
1、创建私有的Spec Repo:
Spec Repo 是所有的Pods的一个索引,是所有公开的Pods 的podspec 文件的一个仓库,其实就是一个部署在服务器的Git仓库,他主要通过各个库的podspec文件来对各个库进行管理。
当你使用CocoaPods 后它会被Clone到本地的 ~/.cocoapods/repos 目录下,目录结构如下:
image.png创建Spec Repo步骤:
(1)在自己的gitlab上新建一个仓库,命名:LHYSpecs
(2)执行:# pod repo add [Private Repo Name] [GitHub HTTPS clone URL]
---->例如:$ pod repo add LHYSpecs http://git.lhycom.com/lhy/LHYSpecs.git (注意把这里地址换成你自己的git仓库地址)
2、通过Xcode创建TestA工程。
(1)在gitlab上新建一个仓库,命名:TestA,然后拉取到本地。
(2)创建一个本地xcode工程,命名TestA。常见方式有两种,第一种是通过终端命令:#pod lib create [项目名],第二种是自己通过xcode创建一个工程。如果使用第二种方式,在创建之后把所有文件拷贝至步骤(1)中的本地仓库。
(3) 配置成私有 Pod
----->配置成私有 Pod 通过命令:pod spec create TestA https://git.coding.net/xxxxxxx/,成功之后会在 TestA工程中生成TestA.podspec文件。
3、通过与步骤2同样的方式创建TestA_Category,并且在Podfile中添加一行pod "CTMediator",然后执行pod install。
4、配置TestA.podspec与 TestA_Category..podspec文件
配置项根据自己需求进行配置,可以参考casa的文章,
配置项的参数意义可以参考下图:
image.png
5、检测TestA.podspec与TestA_Category..podspec是否合法,首先本地验证,然后远程验证。
(1)在Terminal中执行cd进入TDWKit.podspec文件目录
(2)本地验证执行命令:pod lib lint --verbose --allow-warnings --use-libraries
(3)远程验证执行命令:pod spec lint --verbose --allow-warnings --use-libraries
6、如果验证通过则表示两个私有库搭建成功了,如果在验证过程中出了问题则需要对问题进行解决再验证,楼主开发过程中遇到的部分问题放在文章最后。验证通过则可以分别提交TestA与TestA_Category代码到远程仓库,通过sourcetree工具或者命令行都可以。
7、提交podspec至私有Spec Repo,并且打上tag,然后命令:pod repo push [Repo名] [podspec 文件名字]
image.png
查看成果:
image.png
8、至此两个私有库完成了,接下来继续我们的CTMediator。
(1)编辑TestA.podspec,添加依赖:s.dependency "TestA_Category",并且在TestA工程中添加AViewController。写代码的地方在s.source_files = "TestA/Classes//.{h,m}"中的Classes文件夹,这个Classes文件夹是自己建的。
(2)找到TestA_Category.podspec中的s.source_files = "TestA_Category/Classes//.{h,m}",这里的Classes就是写代码的地方,打私有库的时候他也是打的这个文件夹里面的内容。
(3)在TestA_Category工程的Classes文件夹中新建基于CTMediator的Category:CTMediator+A
在CTMediator+A.h中添加一个方法:- (UIViewController *)A_aViewController;
在CTMediator+A.m中实现:
- (UIViewController )A_aViewController
{
/
AViewController *viewController = [[AViewController alloc] init];
*/
return [self performTarget:@"A" action:@"viewController" params:nil shouldCacheTarget:NO];
}
(4)为 TestA工程创建 Target(一个组件对应一个 Target-Action):
此时我们关掉所有XCode窗口。然后打开两个工程:TestA_Category工程和TestA工程。
我们在TestA工程中创建一个文件夹:Target,然后看到TestA_Category里面有performTarget:@"A",所以我们新建一个对象,叫做Target_A。
然后又看到对应的Action是viewController,于是在Target_A中新建一个方法:Action_viewController。这个Target对象是这样的:
image.png
9、至此,就可以通过CTMediator 获取VC了。
UIViewController *viewController = [[CTMediator sharedInstance] A_aViewController];
[self.navigationController pushViewController:viewController animated:YES];
10、遇到的部分问题:
(1)在创建私有库的过程中,如果是使用“ #pod lib create [项目名] ”命令创建的xcode工程,在远程验证(远程验证命令:pod spec lint --verbose --allow-warnings --use-libraries)的时候报下图错误,如果你试了网上所有的方法还不能解决,可以自己创建xcode工程并创建且配置.podspec文件,然后直接用自己创建的.podspec文件替换原有的.podspec文件。
(2)1、当建好了私有库,在Example工程中pod install出现如图报错:target has transitive dependencies that include static binaries:
-------->解决办法:在podspec文件中添加 s.static_framework = true
(3)还有些其他问题记得不是很清楚了,有问题欢迎留言讨论。