如何优雅的实现界面跳转 之 统跳协议 - DarwinNativeRouter
PS 感谢大家的关注,由于我本想开源4个库,除了router, 另外三个分别是native dispatcher, web dispatcher 和 react dispatcher , 所以router 对native dispatcher 有了库依赖,为了共同学习,我把router单独分离成pod,再次感谢大家的关注,欢迎叫router更完善。best regards.
如何优雅的实现界面跳转 之 统跳协议 - DarwinNativeRouter
@author Jou Email Weibo or Github
预热 - 我要解决的问题
首先我还是要推荐Gaosboy的这篇文章解耦神器 —— 统跳协议和Rewrite引擎
文章中,介绍了天猫app,基于文件配置和uri的页面跳转。这大大增加了app端的灵活性, 而这种实现很类似今天的前端或后端开发中的 静态路由 和 动态路由协议。
除了天猫,在很多的客户端架构的文章中,路由解耦的案例并不不少见,如携程移动App架构优化之旅
蘑菇街App的组件化之路
原生路由协议, 其实两年前就有了类似的实现。比如900+Star的HHRouter,而作者是当时还在布丁动画工作的Light。2015年我有幸见到本人,人很nice,并真是全栈。
DarwinNativeRouter 在接口设计上,很大程度上的参考了现有的react路由协议 react router。并且对原生跳转方式保留很大的可扩展性。所以我的初衷 DarwinNativeRouter 是一个足够轻量级的框架。Light & Flexible。
全局路由协议能解决的问题
错中复杂的Controller的跳转依赖
在iOS的世界里,传统的Controller跳转方式, A 跳转 B, 则 A 必须持有 B 的对象。 而在app长大的过程中, 势必会造成 A -> B , B -> C, A -> C D, E, F...
从而产生复杂的依赖链。全局的Router 使 A 不必依赖于 特定的 Controller 便可以实现跳转。
如下面跳转:
We Always Do:
UIViewController *personal = [UIViewController new];
personal.userId = @"";
[self.navigationController pushViewController:personal animated:YES];
Router Code:
[[DNRouter router]open:@"./user/10238372/profile"]; 又比如我们要在navigationController根路径跳转
We Always Do:
[self.navigationController popToRootViewControllerAnimated:NO];
UIViewController *personal = [UIViewController new];
personal.userId = @"";
[self.navigationController pushViewController:personal animated:YES];
Router Code:
[[DNRouter router]open:@"/user/10238372/profile"];
推送通知,点击打开指定页面
对于这种需求, 相信,目前最多的实现应该是两种, 一种的传参的Url, 而另一种,是传递int类型,并通过类似switch case对参数值的硬编码,实现跳转逻辑。
我是很反感第二种的跳转方式, 1. int毫无疑义, 只能硬解释。 2. 跳转的页面有限。 当然如果url采用硬编码, 也是跳转有限的。
而有了router,一切不一样。
从didFinishLaunchingWithOptions 和 didReceiveRemoteNotification捕获payload
跳用Router
Somethings we may do:
switch (type) {
case :
//jumping code
break; case :
//jumping code
break;
case :
//jumping code
break;
case :
//jumping code
break; default:
break;
}
Now we need do:
if([[DNRouter router]canOpen:url.absoluteString]) [[DNRouter router]open:url.absoluteString];
app间通讯 及 deeplink
Router 可以轻松handle deeplink。 deeplink 即: 从safari打开app的指定页面。 这方面做得比较好的, 如新浪微博的app, 在点击对应的新浪微博热点 条目时, 就发生了跳转,并跳到了条目详情。
Router, 同样可以被用作 app 间通讯, 和 deeplink 的原理相同。uri的通讯方式,被认为是最简单的app间通讯。 如我们常常使用的微信分享,配置的 scheme 就是用来做跳转和通讯的。
Router Code
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
if([[DNRouter router]canOpen:url.absoluteString])
{
[[DNRouter router]open:url.absoluteString];
return YES;
}
return NO;
}
一致的行为处理, Hybrid & React Native
有了Router, 你可以使这些跳转 有一致的行为。
DarwinNativeRouter 特性
静态路由 /user
[DNRouter routerWithName:@"profile" path:@"/user"
navigationController:(UINavigationController *)self.window.rootViewController
controller:^__kindof UIViewController *{ UIViewController *controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];
return controller; } action:^(__kindof UIViewController *controller) { [DNDispatcher dispatcher].defaultNavigationController.animation(NO).pushViewController(controller);
// 希望大家注意下动画的设置,若animation设为YES, 容易造成animation system的混乱,需要保证最后一个push的前的所有controller的动画为NO. }];
动态路由 /user/:id
[DNRouter routerWithName:@"profile" path:@"/user/:id"
navigationController:(UINavigationController *)self.window.rootViewController
controller:^__kindof UIViewController *{ UIViewController *controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];
return controller; } action:^(__kindof UIViewController *controller) { [DNDispatcher dispatcher].defaultNavigationController.animation(NO).pushViewController(controller);
// 希望大家注意下动画的设置,若animation设为YES, 容易造成animation system的混乱,需要保证最后一个push的前的所有controller的动画为NO.
}];
更方便的跳转,名称跳转 name jumping
[[DNRouter router]redirect:@"profile"];
相对路径跳转
//跟路径
[[DNRouter router]open:@"/user"]; //当前路径
[[DNRouter router]open:@"./user"]; //上一级
[[DNRouter router]open:@"../user"];
易扩展, 自定义跳转 action
[DNRouter routerWithName:@"profile" path:@"/user/:id"
navigationController:(UINavigationController *)self.window.rootViewController
controller:^__kindof UIViewController *{ UIViewController *controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];
return controller; } action:^(__kindof UIViewController *controller) { [DNDispatcher dispatcher].defaultNavigationController.animation(YES).pushViewController(controller); }];
默认行为,及 异常处理,index & 404
// index page
[DNRouter defaultRouterWithController:^__kindof UIViewController *{ } action:^(__kindof UIViewController *controller) { }]; // 404 page
[DNRouter notFoundRouterWithController:^__kindof UIViewController *{ } action:^(__kindof UIViewController *controller) { }];
后言
DarwinNativeRouter 现在还没有到1.0版本,还有很多可以想象的东西,欢迎让他更加完善,和提pr。
DarwinNativeRouter's Github
@author Jou Email Weibo or Github
如何优雅的实现界面跳转 之 统跳协议 - DarwinNativeRouter的更多相关文章
- 页面解耦—— 统跳协议和Rewrite引擎
原文: http://pingguohe.net/2015/11/24/Navigator-and-Rewrite.html 解耦神器 —— 统跳协议和Rewrite引擎 Nov 24, 2015 • ...
- ASP.Net MVC跳转,分为form的submit提交跳转和ajax跳转
1,用jquery ajax跳转的话,需要在前台用window.location("跳转网址")来跳转,在success后使用 2,用原声的form的submit来跳转,如下图 3 ...
- [HTML]js实现页面跳转,页面A跳到另一个页面B.以及页面传值(中文)
要实现从一个页面A跳到另一个页面B,js实现就在A的js代码加跳转代码 JS跳转大概有以下几种方式: 第一种:(跳转到b.html)<script language="javascri ...
- JSP中客户端跳转与服务器端跳转的区别
转载自:https://www.cnblogs.com/memewry/archive/2012/08/21/2649988.html 客户端跳转时用HttPservletResopse对象的send ...
- react跳转url,跳转外链,新页面打开页面
react中实现在js中内部跳转路由,有两种方法. 方法一: import PropTypes from 'prop-types'; export default class Header exten ...
- 剑指offer例题——跳台阶、变态跳台阶
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 思路: n<=0时,有0种跳法 n=1时,只有一种跳法 n=2时,有 ...
- [Java]Get与Post,客户端跳转与服务器端跳转
http://www.thinksaas.cn/group/topic/133101/ 虽然说get 与post 问题很老套了,但是作为web 开发人员来说对于这个的理解确实很有必要,其实说到get ...
- 7、斐波那契数列、跳台阶、变态跳台阶、矩形覆盖------------>剑指offer系列
题目:斐波那契数列 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). f(n) = f(n-1) + f(n-2) 基本思路 这道题在剑指offe ...
- Web开发中的服务器跳转与客户端跳转
两者比较如下: 跳转类型 客户端请求次数 服务端响应次数 URL变化 站外跳转 作用域 服务器跳转 1 1 无 否 pageContext.request.session.application 客 ...
随机推荐
- bzoj 1391 [Ceoi2008]order(最小割)
[题意] 有n个有偿工作选做,m个机器,完成一个工作需要若干个工序,完成每个工序需要一个机器,对于一个机器,在不同的工序有不同的租费,但买下来的费用只有一个.问最大获益. [思路] 对于工作和机器建点 ...
- Some_problem_with_octopress
今天我总算是使用上了高大上的octopress了,不容易啊,现在我把之前的博客全部搬到了octopress上了,在github上办博客让我不用再担心流量和广告了!---爽啊 我使用octopress时 ...
- Javascript异步请求你能捕获到异常吗?
Javascript异步请求你能捕获到异常吗? 异常处理是程序发布之前必须要解决的问题,不经过异常处理的应用会让用户对产品失去信心.在异常处理中,我们一贯的做法是按照函数调用的次序,将异常从数据访问层 ...
- 第二百八十一、二、三天 how can I 坚持
又是三天,真搞不懂人到底是是什么,到底想要啥,好压抑. 周五,李东勇他们来北京开年会,晚上下班,去了趟团结湖公园,好冷,快冻死了,等着他们来了,见面,感觉好亲切,晚上一块吃了个火锅,玩的很happy. ...
- Gym 100507H Pair: normal and paranormal (贪心)
Pair: normal and paranormal 题目链接: http://acm.hust.edu.cn/vjudge/contest/126546#problem/H Description ...
- 嵌入式LINUX入门到实践(二)
这篇中将围绕韦东山LINUX第二部分教程源码,对IIC协议进行程序实现上的分析. /* I2C registers */#define IICCON (*(volatile unsigned ...
- android EditText控制光标的位置
利用自定义键盘,需要手动删除编辑框中的文本时,会根据光标的位置来删除字符.那么,如何来控制光标呢,android为我们提供了哪些方法,来处理光标呢? 这里提供几个自己写的方法,根据这些方法可以满足在光 ...
- Oracle新建用户、角色,授权,建表空间
oracle数据库的权限系统分为系统权限与对象权限.系统权限( database system privilege )可以让用户执行特定的命令集.例如,create table权限允许用户创建表,gr ...
- Intel® RealSense™ SDK Architecture
In this article, we highlight some of the key changes that you can expect to see in the Intel RealSe ...
- 【不积跬步,无以致千里】关闭631端口cups打印服务和8009端口ajp
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...