热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何优雅的实现界面跳转之统跳协议

如何优雅的实现界面跳转之统跳协议预热–我要解决的问题首先我还是要推荐Gaosboy的这篇文章解耦神器——统跳协议和Rewrite引擎文章中,介绍了天猫app,基于文件配置和uri的页面跳转

如何优雅的实现界面跳转 之 统跳协议



预热 – 我要解决的问题


首先我还是要推荐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 = [UIViewControllernew];

  personal.userId = @"10238372";

  [self.navigationController pushViewController:personal animated:YES];


Router Code:


[[DNRouterrouter router]open:@"/user/10238372/profile"];


推送通知,点击打开指定页面


对于这种需求, 相信,目前最多的实现应该是两种, 一种的传参的Url, 而另一种,是传递int类型,并通过类似switch case对参数值的硬编码,实现跳转逻辑。
我是很反感第二种的跳转方式, 1. int毫无疑义, 只能硬解释。 2. 跳转的页面有限。 当然如果url采用硬编码, 也是跳转有限的。
而有了router,一切不一样。


  1. 从didFinishLaunchingWithOptions 和 didReceiveRemoteNotification捕获payload

  2. 跳用Router


Somethings we may do:


switch(type){

  case 1001:

    //jumping code

    break;

 

  case 1002:

    //jumping code

    break;

  case 1003:

    //jumping code

    break;

  case 1004:

    //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([[DNRouterrouter]canOpen:url.absoluteString])

  {

    [[DNRouterrouter]open:url.absoluteString];

    returnYES;

  }

  returnNO;

}


一致的行为处理, Hybrid & React Native


有了Router, 你可以使这些跳转 有一致的行为。


DarwinNativeRouter 特性


静态路由 /user


[DNRouter routerWithName:@"profile" path:@"/user"

    navigationController:(UINavigationController*)self.window.rootViewController

              controller:^__kindofUIViewController *{

 

  UIViewController*controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];

  returncontroller;

 

} action:^(__kindofUIViewController*controller){

 

  [DNDispatcherdispatcher].defaultNavigationController.animation(YES).pushViewController(controller);


}];


动态路由 /user/:id


[DNRouter routerWithName:@"profile" path:@"/user/:id"

    navigationController:(UINavigationController*)self.window.rootViewController

              controller:^__kindofUIViewController *{

 

  UIViewController*controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];

  returncontroller;

 

} action:^(__kindofUIViewController*controller){

 

  [DNDispatcherdispatcher].defaultNavigationController.animation(YES).pushViewController(controller);

 

}];


更方便的跳转,名称跳转 name jumping


[[DNRouterrouter]redirect:@"profile"];


相对路径跳转


//跟路径

[[DNRouterrouter]open:@"/user"];

 

//当前路径

[[DNRouterrouter]open:@"./user"];

 

//上一级

[[DNRouterrouter]open:@"../user"];


易扩展, 自定义跳转 action


[DNRouter routerWithName:@"profile" path:@"/user/:id"

    navigationController:(UINavigationController*)self.window.rootViewController

              controller:^__kindofUIViewController *{

 

  UIViewController*controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];

  returncontroller;

 

} action:^(__kindofUIViewController*controller){

 

  [DNDispatcherdispatcher].defaultNavigationController.animation(YES).pushViewController(controller);

 

}];


默认行为,及 异常处理,index & 404


// index page

[DNRouter defaultRouterWithController:^__kindofUIViewController *{

 

} action:^(__kindofUIViewController*controller){

 

}];

 

// 404 page

[DNRouter notFoundRouterWithController:^__kindofUIViewController *{

 

} action:^(__kindofUIViewController*controller){

 

}];


后言


DarwinNativeRouter 现在还没有到1.0版本,还有很多可以想象的东西,欢迎让他更加完善,和提pr。


DarwinNativeRouter’s Github


推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • Android获取app应用程序大小的方法
    Android获取app应用程序大小的方法-Android对这种方法进行了封装,我们没有权限去调用这个方法,所以我们只能通过AIDL,然后利用Java的反射机制去调用系统级的方法。 ... [详细]
  • MySQL8.0设置远程访问权限的方法
    这篇文章主要介绍了MySQL8.0设置远程访问权限的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着 ... [详细]
  • 用户视图(查看运行状态或其他参数)系统视图(配置设备的系统参数)system-viewEntersystemview,returnuservi ... [详细]
  • Myappcrashedandthecodeisthefollowing:我的应用程序崩溃,代码如下:elseif(){CGDetailVie ... [详细]
  • Request对象和Response对象request:(请求)当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象。Djang ... [详细]
  • 代码如下:Stringpathrequest.getContextPath();StringbasePathrequest.getScheme():request ... [详细]
author-avatar
杜_森后_665
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有