☆☆☆ “RouteManager” ☆☆☆
支持 pod 导入
-
pod 'RouteManager'
-
执行 pod search RouteManager 提示搜索不到,可以执行以下命令更新本地 search_index.json 文件
rm ~/Library/Caches/CocoaPods/search_index.json
- 如果 pod search 仍然搜索不到,执行 pod setup 命令更新本地 spec 缓存(可能需要几分钟),然后再搜索
前言
-
GitHub 上一些主流的路由和中间件实现方案,比如 JLRoutes、MGJRouter、HHRouter、CTMediator
-
JLRoutes 提供的功能很多很杂,让人难以全面掌握,修改麻烦,甚至需要服务端提供支持,
-
MGJRouter 的设计让项目新人难以快速上手,成本高,代码写法略装逼,
-
CTMediator 是我个人比较喜欢的库,在我们的项目中使用了 CTMediator 中的部分代码,
-
以上几个库都解决了根据路由规则进行控制器的 push 操作,但都忽视了回调操作(比如 delegate 回调),我主要想解决这个问题,在 CTMediator 原有的基础上再次进行了封装,优化。
-
-
无论是路由还是中间件,主要目的:功能模块解耦,同时降低业务耦合度;满足多样化的 app 使用场景,比如在 H5 点击某个链接可以跳转到原生页面;从 app 外部点击某个链接跳转到 app 内部某个功能场景
-
移动端路由其实参照的是 web 端的路由实现方案。web 端的路由实现方案,说白了,就是将路由地址和响应事件做一个关系映射,当客户端访问某个 URL 时,系统就会调用这个 URL 对应的响应方法
架构怎么进化
-
架构进化体现在哪些方面,作为一个技术团队,我们要如何把架构进化落地?这个问题因项目而异,因团队而异,因方向而异。本文只介绍手机天猫在发展过程中,与解耦相关的进化历程。
-
升级开发模式
- 开发模式的概念有点大,本文就只讨论和解耦这件事相关的:团队合作方式和工程组织形式。下文单独一节聊这个事,此处不赘述。
-
各维度解耦
- 工程大了以后,要分拆,不管是组件化还是插件化,还是什么,解耦是第一步,而且是各个维度的解耦。
-
完善工具集
- 模式演进的过程中,解耦的过程中,就会衍生出很多的工具。在进化过程里我们也会去思考,哪些工作是需要工具化的,主动去开发工具。一个完善的工具集,会极大提升团队的生产力,可以说是最有价值的部分。
开发模式升级
-
模块化
- 先按功能把工程做横向分层,在业务层再做纵向梳理。把不同的模块代码简单地放在一个文件夹里,而工程的组织形式并没有发生变化。跨团队基本不会在同一个模块代码上产生冲突。
-
插件化
- 随着业务的进一步发展,业务越来越复杂,团队工作越来越细分,人员也越来越多,代码量也越来越大。简单地使用文件夹来组织模块的方式显得力不从心。多业务跨团队,不同的开发节奏,复杂的依赖关系,导致我们花费大量时间解决编译不过的问题。等待其他模块集成的这件事竟然成了我们开发效率最大的瓶颈。
-
插件化
-
代码独立,首先从形式上解耦
-
独立代码工程化,为独立运行打下基础
-
梳理依赖关系,独立工程可编译
-
放弃源码依赖,提速集成编译
-
解耦思路
-
工欲善其事,必先利其器。虽然大家都这么说,但并不是每个人都能做到。一个拥有强烈工具文化的团队在质量,效率等各个方面都会有很大的优势。
-
一个工程,从原始状态迅速膨胀到天猫现在的规模,依赖关系之复杂,超乎想象。
-
耦合可分为三类:
-
界面耦合,就是用户操作流程中,不同界面之间的跳转,这些跳转是硬编码的
-
依赖耦合,顾名思义,两个模块之间存在依赖,即为耦合
-
工程耦合,每个模块有自己的生命周期和运行时,但在生产环境中,每个模块又需要依赖于主工程的运行时
-
放弃源码依赖,提速集成编译
-
使用
-
路由无参数
- 从 ViewController 向 TestViewController 跳转,在 ViewController 中将通过路由找到 TestViewController
UIViewController *doc = [[RouterManager sharedInstance]
performAction:@"TestViewController"
params:nil
shouldCacheTarget:NO];
[self.navigationController pushViewController:doc animated:YES];
-
路由带有参数
- 从 ViewController 向 TestViewController 跳转,在 ViewController 中将通过路由找到 TestViewController,并将传入的参数赋值给目标控制器。在 TestViewController 中只需声明一下入参接收对应的 key
@implementation UIViewController (routerManager)
- (id)createVC:(NSDictionary *)dict{
Class class = getClassFromAtcion(_cmd);
if (class) {
UIViewController *doc = self;
doc = [[class alloc]init];
doc = [doc mj_setKeyValues:dict];
return doc;
}
return nil;
}
@end
UIViewController *doc = [[RouterManager sharedInstance]
performAction:@"TestViewController"
params:@{
@"info":@{
@"user":@"我是正向传值参数:push",
}
}
shouldCacheTarget:NO];
[self.navigationController pushViewController:doc animated:YES];
-
路由带有参数且回调反向传值
- 在 ViewController 和 TestViewController 中同时声明一个 block,demo 中有详细说明
- (IBAction)popBtnClick:(UIButton *)sender
{
self.backblock(@"我是返回值参数:pop");
[self.navigationController popViewControllerAnimated:YES];
}
__weak typeof(self) weakSelf = self;
self.backWithDict = ^(NSString *str) {
weakSelf.backLabel.text = str;
};
UIViewController *doc = [[RouterManager sharedInstance]
performAction:@"TestViewController"
params:@{
@"info":@{
@"user":@"我是正向传值参数:push",
},
@"backblock":self.backWithDict
}
shouldCacheTarget:NO];
[self.navigationController pushViewController:doc animated:YES];