正文
输入的方法统一了,输出也得统一,没有规矩不成方圆,但又不能通过说教的方式要求大家去提供输出方法。如果有一个统一的办法可以不需要协议注册,协议管理的机制,直接写一个类方法可以让 JDRouter 通过 URI 里的内容可以映射过去就好办了,我们使用宏替换,在 JDRouter 里提供一个输出的规范,类似这样:
#define JDROUTER_EXTERN_METHOD(m,i,p,c) + (id) routerHandle_##m##_##i:(NSDictionary*)arg callback:(Completion)callback
输出规范统一,将上面的类方法变为宏替换输出:
JDROUTER_EXTERN_METHOD(JDBClass, eat, getString, callback) {
NSString *str = [NSString stringWithFormat:@"HI, %@", name];
return str;
}
页面容器,第三方 SDK 初始化工作需要在启动时完成,我们通过 hook AppDelegate,将入口所做的工作交给一个组件完成,在该组件中注册其它需要在启动时调用 AppDelegate 方法的组件,让每个组件都可以拥有一类似 didFinishLaunchingWithOptions 方法。
+ (void) load {
NSArray *modules = @[@"MainModule"];
NSString *url = @"router://AppDelegateModule/setDidFinishLaunchingModules";
[JDRouter openURL:url arg:modules error:nil completion:nil];
//
NSString *urlrun = @"router://AppDelegateModule/run";
[JDRouter openURL:urlrun arg:nil error:nil completion:nil];
}
在 MainModule 中实现 AppDelegate 的方法
static UIWindow *gWindow = nil;
static UIViewController *gTempViewController = nil;
+ (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
gWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[[[UIApplication sharedApplication] delegate] setWindow:gWindow];
gTempViewController = [[UIViewController alloc] init];
gTempViewController.view.backgroundColor = [UIColor redColor];
gWindow.rootViewController = gTempViewController;
[gWindow makeKeyAndVisible];
return YES;
}
把实例方法改为类方法
将需要调用 appdelegate 方法的组件,在 MainModule 中注册,这里的 modules 是个数据,可解决调用 delegate 方法的顺序问题。
NSArray *modules = @[@"MainModule", @"需要调用的组件"];
代码解耦很简单,只要遵循几个原则即可,最根本的问题就是业务与业务之间不能有耦合,不然组件化这件事就没有意义。我们通过 Cocoapods 把每一个组件都拆成独立的 pod 库。代码库管理选择 gitlab(开源,提供 API,可二次开发),后续需要对每一个组件进行权限管理,比如有一些涉及到安全的组件只有安全组的开发人员具体源码权限,其他人只能拿到二进制,再比如组件需要具有 master 的权限才可以进行发布,集成等工作。
关于 Cocoapods,ruby,gitlab 环境大家网上搜索一下。
准备工作
-
通过 Cocoapods 搭建私有库,创建相应的模版。
-
不推荐 Cocoapods 编译二进制文件,自己写脚本编起来更灵活。
-
自定义 gem,完成 podspec 源码二进制切换。
-
二进制文件(组件编译为静态包)存储到内部云。
-
使用工具/脚本管理 podfile。
-
系统管理 pod 库。
-
工程结构
-
通过 Cocoapods 搭的自定义库,自定义模版。
每个同学拿到的组件都是一个相同结构的工程,所需要做的工作就是在相应的 Pods/Developemnt Pods/ 组件 /Classes 下编码,组件输出类通过模版创建,可在相应的类里使用 JDROUTER_EXTERN_METHOD 提供接口。
以上是行业中对 iOS 组件化的一个大体思路。如果我们完全手动做这些工作的话,成本会很大,Cocoapods 配置说明查询,组件版本依赖,统一集成等等。为了解决这些人为干预所引发的各种问题,我们研发了组件管理系统
iBiu
。
主 App 解耦工作和系统设计是同时进行的,所以最初系统只是为京东 iOS 主 App 所设计,在独立出一些组件后,我们就在思考一件事,让系统可管理京东其它的 App。