TKRouter
介绍
万能路由 API 功能:
1. Api 万能路由利用 AOP 编程思想,指针参数,等来实现任意 object-c 的 API 调用。支持基本数据类型,对象类型,代理,block,枚举,结构体等(系统自带和自定义均支持)
2. 本 sdk 用于组件化开发模式,多 sdk 嵌套等复杂的情况!完全解决项目开发的耦合度!
背景
组件开发模式:在大型项目开发中,有多个 sdk 一起进行开发。主 app 只是一个空壳,各个组件 sdk 开发完成后进行 pod 验证,打 tag,执行 repo push 操作,最后提交到公司仓库。然后只需要在主 app 进行多 pod 依赖,一键 pod update!把各个组件 sdk 拉下来!这就是最常用的组件开发。我的公司也是这种开发模式。 组件化开发的好处这里不做赘述!网上有很多资料,可以说大型项目已经离不开组件化的思想。
组件化路由:在这样的开发模式下,效率大大提升,并且分工明确,各个团队之间有条不紊。而在各个团队之间的桥梁——路由的作用就不言而喻!常规的路由,包括目前流行的路由三方组件,都有自己的定义规则,一个项目突然适配起来并不是那么简单。
开发问题:主 app 包含多个组件(例如,比如 2 个组件,像京东商城,支付宝这样的级别有 100 个左右),比如组件 A 和组件 B。分属两个团队负责开发,都有自己完整的流程!那么两个库都依赖了 AFNetworking 这个请求第三方(大公司会封装自己的请求框架轮子)。这里以 AFNetworking 为例来示范一下,毕竟太牛了!哈哈 A 单独开发:A 项目,引入 pod 'AFNetworking', '> 3.0' 然后 高高兴兴去开发了,在项目期限结束时,打 tag,pod lib 验证,pod repo push 完成。B 单独开发:B 为老组件,很早就引入 pod 'AFNetworking', '> 2.0' 然后 高高兴兴去开发了,在项目期限结束时,打 tag,pod lib 验证,pod repo push 完成。两个库都很 okay!
主 app 进行 pod 依赖,把各个组件下载下来 pod 'A 组件',pod 'B 组件'!
1. 这时候执行 pod update 就出现问题了,拉不下来,因为 pod 版本不兼容。 记作 问题一
主 app 负责人看了,会有两种解决方案
方案一:立即联系 B,告知版本库升级到 3.0 使用新的,告知所有团队以某个版本为准。
方案二:把 AFNetworking 作为主 app 的直接 bundel 内容,其它组件去掉 AFNetworking
对于方案一:版本冲突解决了,但是有 100 个组件依赖于 100 个 AFNetworking,有的组件提供源码,没问题,源码只会拉一份,有的提供的 framework,经过 pod 打包默认加前缀的(无 --no-mangle 命令)!也就是说有多少个静态库提供的组件,就会生成同样功能的 AFNetworking,比如有 50 个组件是静态库,那么最后拉下来就会有 51 个 AFNetworking 存在项目中。(如果不加 --no-mangle)对于静态库类型的组件,就会报错有很多个重复文件。---记作 问题二
对于方案二:主 app 管理 AFNetworking,那么在 A 和 B 单独开发的时候,不能依赖于 AFNetworking,只能导入主.h 文件,将 AFNetworking 作为 demoApp 加入 demo 工程。也可以正常开发。但是进行 pod lib 和 pod repo push 就推不上仓库了!因为 pod 验证会检测实现方法等,相当于没有 AFNetworking 库,直接通不过。--记作 问题三
以上问题对组件型的 APP 开发造成很大的困扰!为了解决这个问题,大牛们早就开始了行动,于是“组件二进制化||平滑二进制组件”的理念诞生了。我也在使用。原理就是把第三方共用组件比如 AFNetworking 先做成二进制文件,大家都依赖二进制文件来实现统一!能极大解决问题,弊端是需要维护很多二进制,并且每次升级不同团队都要做二进制文件的 md5 哈希取值,这个值一样才能说明是同一份!每次代码升级开发完毕,必须把源码重新生成新的二进制,维护成本很高!有时候就忘记了!
针对诸多问题,我就尝试了 TKRouter 的实现。
TKRouter
1.调用原子api ,没有什么规则,就像调用方法一样。
2.多组件开发,都依赖某些第三方组件的时候,比如AFNetworking,我们一旦确定几百个团队有一个在用AFNetworking,那么我们就不管依赖的事情了
甚至不去维护它,瞅一眼都懒! 我们就直接路由调用。我们的项目和AFNetworking无任何直接关系,头文件都不需要引入。
下面是我的某个组件调用 AFNetworking 的网络检测代码:
常规实现:
-
项目依赖 AFNetworking
-
实现的地方引入 AFNetworkReachabilityManager.h
-
实现如下代码
AFNetworkReachabilityManager *maneage=[AFNetworkReachabilityManager sharedManager]; [maneage startMonitoring]; [maneage setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { if (status == 0) { //无网络链接 } else { //有网链接 } }];
TKRouter 实现:直接上代码,不要依赖,不需要引入头文件:
ReturnStruct managerStur = [[[TKRouter router] routerClassName:@"AFNetworkReachabilityManager"] classMethodSelect:@"sharedManager" parameter:nil, nil];
NSObject *objManager = managerStur.returnValue;
[objManager instanceMethodSelect:@"startMonitoring" parameter:nil, nil];
void (^ReachabilityStatusChangeBlock)(NSInteger status) = ^(NSInteger status){
if (status == 0) {
//无网络链接
} else {
//有网链接
}
};
[objManager instanceMethodSelect:@"setReachabilityStatusChangeBlock:" parameter:&ReachabilityStatusChangeBlock, nil];
TKRouter的优点在于无需关心依赖的框架,只要主APP或主APP依赖的组件有相应的SDK,我就能够通过TKRouter进行调用。即使组件工程中没有AFNetworking也能执行pod lib lint和pod repo push!推送的是组件,若要达到实际效果,只需在demo工程中手动导入AFNetworking即可。Pod推送和验证与demo工程无关。
以上所有问题都得到了解决,而且没有任何成本!
注意事项:TKRouter强大的原子调用无需置疑,一旦第三方SDK开源,API就会固定。因此,主工程中有数百个组件只需要一个AFNetworking即可,因为AFNetworking的API通常不会随着版本升级而改变,只有实现部分会有所改变。但我们对这些并不关心,有其他团队来维护。
好处:我们不需要关心它升级到第几个版本,让其他团队更新维护版本,而我们只关注API!
注意:如果某个开源库万不得已改变了API!由于我们使用路由AOP思想编写的程序,API变化时,我们组件并没有报错或出现红点提示。因此,每次开源库进行大版本升级时,只需关注API的变化即可。这样的情况大概万年难得一见!
不要告诉我,你自己懒到连自己的代码都愿意写一辈子都不维护。
示例
调用注意:我们所有的方法参数都是指针类型!这涉及到左值和右值方面的知识。我们传递的是左值-内存中具有实际内存的。有兴趣的小伙伴可以研究一下。为了简单起见,如果方法是传递的值,直接使用会报错,我们定义一个它的对象,接收值,然后使用新定义的对象取地址即可。左值、左值引用、右值、右值引用:https://www.jianshu.com/p/8095517dbb3f
核心方法:
一: /** 实例化对象,给属性赋值 @param propertyParameter 属性字典组合。 key为属性的字符串。 value为属性需要赋予的值 @return 返回 */
- (ReturnStruct)setPropertyParameter:(NSDictionary*)propertyParameter;
二: /** 执行实例方法
@param selectString 方法名 @param methodParaments 方法参数 --- 指针参数 对应参数以指针类型传入 @return 返回值 */
- (ReturnStruct)instanceMethodSelect:(NSString*)selectString parameter:(void *)methodParaments, ... NS_REQUIRES_NIL_TERMINATION;
三: /** 执行类方法
@param selectString 方法名 @param methodParaments 方法参数 --- 指针参数 对应参数以指针类型传入 @return 返回值 */
- (ReturnStruct)classMethodSelect:(NSString*)selectString parameter:(void *)methodParaments, ... NS_REQUIRES_NIL_TERMINATION;
比如在demo工程:
调用方法:+ (NSString*)TestMethodOneWithObjectType:(NSDictionary*)dic andPar:(NSString*)strOne andPar:(NSNumber*)numTwo;
Class TKMethodTestClass = [[TKRouter router] routerClassName:@"TKMethodTest"];
//step 二: AOP 调用+ 方法。即类方法
NSDictionary *par1 =@{@"key1":@"Hello:TKRouter",@"key2":@"SayHi"};
NSString *par2 = @"字符串类型参数";
NSNumber *par3 = [NSNumber numberWithInt:1688];
[TKMethodTestClass classMethodSelect:@"TestMethodOneWithObjectType:andPar:andPar:" parameter:&par1,&par2,&par3, nil];
调用方法:- (void)TestMethodTwoWithBasicType:(int)numberone andSecond:(CGFloat)floatTwo;
//步骤四: 实例对象调用 - 方法 - 传入基本数据类型
NSObject *object = [[TKRouter router] routerGetInstanceWithClassName:@"TKMethodTest"];
int par4 = 8888;
CGFloat par5 = 88.88;
ReturnStruct returnOne = [object instanceMethodSelect:@"TestMethodTwoWithBasicType:andSecond:" parameter:&par4,&par5, nil];
调用方法:- (BOOL)TestMethodTwoWithStructType:(CGRect)struOne and:(CGSize)struTwo; //步骤四二: 实例对象调用 - 方法 - 传入结构体
NSObject *object = [[TKRouter router] routerGetInstanceWithClassName:@"TKMethodTest"];
CGRect par6 = CGRectMake(100, 100, 200.5, 200);
CGSize par7 = CGSizeMake(666.0, 888.5);
ReturnStruct returnTwo = [object instanceMethodSelect:@"TestMethodTwoWithStructType:and:" parameter:&par6,&par7, nil];
调用方法:- (NSString*)TestMethodTwoWithBlockType:(void(^)(NSString *str1))block;
//步骤四三: 实例对象调用 - 方法 - 传入block块
NSObject *object = [[TKRouter router] routerGetInstanceWithClassName:@"TKMethodTest"];
void(^parblock8)(NSString *str1) = ^(NSString *str1){
NSLog(@"\n block 得到的值回调。==%@\n\n\n",str1);
};
ReturnStruct returnThere = [object instanceMethodSelect:@"TestMethodTwoWithBlockType:" parameter:&parblock8, nil];
以上是基础的调用方式,更多详情请下载查看。
比如:初始化ctrl,TKRouter给ctrl赋值,TKRouter调用push,弹出新的视图,TKRouter设置代理!实现基本数据类型、结构体、OC类型、block块、代理等!
安装
TKRouter可通过CocoaPods获得。要安装它,只需将以下行添加到您的Podfile中
pod 'TKRouter'
作者
Tkoul, [email protected]
许可证
TKRouter可在MIT许可证下使用。有关更多信息,请参阅LICENSE文件。