如何优雅的实现界面跳转 之 统跳协议 - 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 4448 [Scoi2015]情报传递(主席树,LCA)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4448 [题意] 给定一颗树,询问一条路径上权值小于t-c的点数. [思路] 将一个2查 ...
- 【转】Nginx系列(三)--管理进程、多工作进程设计
原博文出于:http://blog.csdn.net/liutengteng130/article/details/46700999 感谢! Nginx由一个master进程和多个worker进程组 ...
- 通用FASTREPORT打印模块及接口方法
untFastReport.dfm文件: object frmFastReport: TfrmFastReport OldCreateOrder = False Height = 405 Width ...
- Spring Data JPA 教程(翻译)
写那些数据挖掘之类的博文 写的比较累了,现在翻译一下关于spring data jpa的文章,觉得轻松多了. 翻译正文: 你有木有注意到,使用Java持久化的API的数据访问代码包含了很多不必要的模式 ...
- Tiny6410声卡驱动——录音与回放
在Linux下,音频设备程序的实现与文件系统的操作密切相关.Linux将各种设备以文件的形式给出统一的接口,这样的设计使得对设备的编程与对文件的操作基本相同,对Linux内核的系统调用也基本一致,从而 ...
- easyUI之tree
转自:http://www.cnblogs.com/CoreCaiNiao/archive/2010/08/20/1804387.html http://blog.csdn.net/l27775918 ...
- Spring3.0 AOP 详解
一.什么是 AOP. AOP(Aspect Orient Programming),也就是面向切面编程.可以这样理解,面向对象编程(OOP)是从静态角度考虑程序结构,面向切面编程(AOP)是从动态角度 ...
- iOS 使用compare 进行对比
compare 是 NSString 中的一个方法,这个方法是将字符串 按照 ACSII码表来进行对比. NSString *num1 = @"5.2.0"; NSString * ...
- 权限检查联系人ProfileProvider
每日一贴,今天的内容关键字为权限检查 ProfileProvider继承自AbstractContyactsProvider. 源代码请自行下载 每日一道理 书籍好比一架梯子,它能引领人们登上 ...
- 【工作记录】android手势事件操作记录
/* 用户按下触摸屏.快速移动后松开 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float vel ...