模块化和组件化在当下的iOS开发中已经深入人心,App的代码不会全部都放在一个主工程里。尤其是开发人员越来越多,业务越来越复杂,代码量越来越多,模块化/组件化开发变得尤为重要。这样做的好处有:
- 解耦:避免代码严重合耦,增加复用和扩展难度;
- 结构清晰,易读,易维护;
- 开发效率高:可独立开发、测试、维护每个模块或组件,开发效率高。
目前组件化开发的方式大约有三种:protocol - class、url - block以及CTMediator target - action方案。博主在项目中使用到的是CTMediator target - action方案,本文将介绍CTMediator的使用,博客大纲如下。

1.CTMediator工作原理
1.1 源码分析

CTMediator的源码就2个文件和2个m文件。核心的代码在CTMediator.m中,而CTMediator+HandyTools扩展类的作用是实现ViewContronller的切换。
查看CTMediator.h文件可以看到,它支持远程App调用和本地组件调用两种方式。
#import <Foundation/Foundation.h>
extern NSString * _Nonnull const kCTMediatorParamsKeySwiftTargetModuleName;
@interface CTMediator : NSObject
+ (instancetype _Nonnull)sharedInstance;
// 远程App调用入口
- (id _Nullable)performActionWithUrl:(NSURL * _Nullable)url completion:(void(^_Nullable)(NSDictionary * _Nullable info))completion;
// 本地组件调用入口
- (id _Nullable )performTarget:(NSString * _Nullable)targetName action:(NSString * _Nullable)actionName params:(NSDictionary * _Nullable)params shouldCacheTarget:(BOOL)shouldCacheTarget;
- (void)releaseCachedTargetWithFullTargetName:(NSString * _Nullable)fullTargetName;
@end
// 简化调用单例的函数
CTMediator* _Nonnull CT(void);
- 远程调用
通过scheme://[target]/[action]?[params]调用。回调写在AppDelegate中,暴露的scheme写在info.plist中。如果你对微信登录非常熟悉的话,那么理解CTMediator的远程调用就非常容易了。其做法是一样的。我们查看CTMediator.m的代码,看看如何实现远程调用的,代码分析如下:
/*
scheme://[target]/[action]?[params]
url sample:
aaa://targetA/actionB?id=1234
*/
- (id)performActionWithUrl:(NSURL *)url completion:(void (^)(NSDictionary *))completion
{
if (url == nil||![url isKindOfClass:[NSURL class]]) {
return nil;
}
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:url.absoluteString];
// 遍历所有参数
[urlComponents.queryIt