iOS 组件化-路由解耦思想 JLRoutes 实战篇(一)App内控制器跳转

Router

前言

组件化, Router 这些概念可能在几年前还是比较新颖的概念, 至今相信绝大多数同学都对这些名词已耳熟能详, 笔者在真正接触到 Router 并在项目使用之前, 也有读过一些 组件化, Router 进行解耦的思想和框架的文章, 但是由于自己修行不够, 加上没能真正将其运用到项目进行实践。 导致每次读完文章之后, 所理解的知识没能真正转化为可以解决问题的技能, 笔者有幸在项目中接触并运用著名开源库 JLRouter 来解决 App 内外所有页面之间的跳转逻辑, 经过这几年的学习和使用, 将其记录一边巩固知识, 写出来跟大家一起学习, 加上看到网上分享关于使用组件化-Router 相关文章偏于理论, 很少有完整详细Demo, 具体在项目中使用还需进一步深入研究, 所以有了此篇文章, 有什么不对或需要补充的, 望大家多多指教。
此篇文章偏向实战, 想深入学习 Router 思想的推荐霜神写的 iOS 组件化 —— 路由设计思路分析

Demo 在文章最👇

为什么 Router

路由基础三问, 每次接触新颖思想框架时, 我都会不禁的问自己这几个问题, 希望通过下面几个简要的概括, 能很好的帮助大家理解 Router;

  • 路由是什么,解决了什么问题

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EpAaUx7y-1576740684933)(https://s2.ax1x.com/2019/12/18/QHTdhR.md.png)]
    上面一幅图很形象的展示了项目中各个控制器模块之间错综复杂的关系, 当我们在处理不当的情况下可能更加糟糕.
    使用 Router 之后大概是这样的;
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i6ZGbHsh-1576740684934)(https://s2.ax1x.com/2019/12/18/QHr2kD.png)]
    打个比方, Router 就是跟我们日常使用的路由器一样, App 内每个控制器可以想象成已经连接了这台路由器的不同设备, 当然连接路由器时, 一般需要输入密码, Router 同样的, 使用前需要每台设备进行一次注册, Router 在内部保存每台设备的 URL, 不同设备之间需要交互时, 将消息发送到路由器中统一处理;
    当控制器之间需要交互跳转时, 只需要将对应的 URL 地址发送到 Router 里, Router 根据其注册的 URL 来寻址到对方信息, 然后负责实例化对象, 并传参, 进行跳转等工作, 各个控制器之间不需要相互依赖对方, 完美解决不同模块之间耦合!

  • 为什么要用路由来实现 VC 跳转
    Router 能做的事情很多, 首先我们用它来解决棘手的控制器耦合关系,是一种非常有效的解决方案;
    在 App 中控制器跳转普遍分为 3 种, 模态跳转Modal(presented/dismiss), 导航控制器跳转(Push/pop), Storyboard 跳转(Segue), 还有 UITabBarVC 主控制器 Index 切换;
    除了常规的控制器之间跳转之外, 还会有 3D Touch 指定跳转到某个控制器中;
    App 之间跳转: URL Scheme, Universal Links方式;
    可想而知 App 内不管是页面切换, 外部调用, 都会涉及到控制器的跳转, 切换等等;
    下面引用常见场景来举个栗子:
    Router 前 伪代码:

假如在没有引入 Router 之前, 实现 A Push B, B Modal C 的场景: 一般做法都是在 A 中引入B, B 中引入 C, 然后在每次跳转前都需要来一段硬编码,

//A Push B   A 页面跳转至 B页面, 并且设置相应 @perpeoty, callback 等;
#import "B"
B* BVC = [B new]; 
BVC.delegate = A;
BVC.name = @"jersey";
BVC.callback = ^ (id data) {
};
... 
...
... 对 b 设置一些业务相关参数, delegate,  callback 等等;
[A.nav pushVC: BVC animation: true]; 
// B -> C 
#import "C"
C* CVC = [C new];
[B presentVC: CVC];
[B presentVC: CVC animation: true completion: nil];

Router 后 伪代码:

在引用了 Router 之后, 相同的场景下, 我们的代码是这样的; 在需要做跳转的控制器引入我们封装好的 JSDVCRouter(是针对 JLRouter 进行的一层封装, 专门用于管理 App 跳转的类, 在文章后面会详细讲解) 即可.

    // A Push B;
    #import "JSDVCRouter"
    [JSDVCRouter openURL: BVCPath info: @{@"delegate":self,@"name":@"jersey",@"callback":callback}];    
    // BVCPath: 表示我们对 B 控制器定义的路径, 一般保存在全局 Map 里面, 每个 Path 映射当前控制器 Map 包含相关 title, class, needLog, 等参数;
    // B Modal C
    [JSDVCRouter openURL: C info: {kJSDRouteSegue: @"Modal"}]; // 控制器之间跳转默认以 Push 实现, 当需要 Modal 时, 则传递一个参数; 

看到这里相信认真阅读的同学们已看出使用 Router 的好处:
1. 耦合度降低: A 控制器不需要知道 B 控制器的存在, 只需要 import “JSDRouter”, 由其去进行相应跳转逻辑, 以及赋值等等;
2. 代码阅读性提高: 当然在刚刚接触时, 看着会不大不习惯, 等接触一段时间之后, 不仅减少了代码行数, 同时可读性还是很高的, 跟 push/pop, present/dismiss 说再见吧;
3. 提高代码复用性: 每次控制器之间跳转和赋值等操作, 都需要重复性的 code 一次**(严重违背了: 可复用性原则)**, 通过 JSDRouter 将跳转和赋值等逻辑封装起来, 一次 code, 终生受用;
4. 易于维护: 写到这一点有点儿纠结, 当项目随着公司规模不断壮大时, 控制器数量, 跳转变得越加复杂, 跳转方法和逻辑很容易变得越来越混乱, 后期管理起来比较困难。 使用 JSDVCRouter 单一职责的原则来专门负责 App 内所有的跳转, 能非常有效的提高测试及后期维护, 当然成本是需要维护 RouterMap 同时完善 JSDVCRouter 内部逻辑;
5. 动态化及灵活性: 使用 Router 时可以配合后台响应传递响应的 Key 来决定真正跳转的页面, 而不是硬编码的方式来进行跳转;
6. 待补充:

  • 实现 Router 完成控制器跳转, 至少需要几个步骤?
    首次将控制器跳转转成 Router 方案
    很简单只有 3个步骤, 如何需求变动不大的话, 几乎一劳永逸;
  1. Map 表创建: 其是一个全局 Map, App 内相应的控制器定义好 Path, Router 可以根据 Path 映射相应控制器制定的 Map 内, Ma
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值