美文网首页
代码解耦-iOS应用內动态跳转解决方案 Routable-iOS

代码解耦-iOS应用內动态跳转解决方案 Routable-iOS

作者: sands_yu | 来源:发表于2017-02-23 10:30 被阅读715次
title: 代码解耦-iOS应用內动态跳转解决方案 Routable-iOS简单使用 
tags: [iOS,开发,APP]

前言

在APP开发过程中,必然会遇到在WebView和推送消息中打开其他页面的需求,进一步则是在任何动态界面.

但随着APP越来越大,功能模块越来越复杂,采用传统的控制器跳转方式,需要持有跳转对象,就会造成复杂的依赖链,代码耦合性变强.

采用Routable的方式进行动态界面跳转则不会有这个问题.

传统跳转:

ProjectDetailViewController* pro = [[ProjectDetailViewController alloc]init];
pro.StrID = @"XX";
pro.Memo = @"XX";
[self.navigationController pushViewController:pro animated:YES];

Routable跳转:

[[Routable sharedRouter] open:@"ProjectDetail/XX/XX"];

Routable使用

1.注册协议

//一般在APP入口didFinishLaunchingWithOptions中进行注册
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    //map规则 @"跳转标识/:参数1/:参数2...."
    [[Routable sharedRouter] setNavigationController:nav];
    [[Routable sharedRouter] map:@"ProjectDetail/:StrID/:Memo/:Name" toController:[ProjectDetailViewController class]];
}

2.使用协议进行跳转

//open规则 @"跳转标识/参数1/参数2"
[[Routable sharedRouter] open:@"ProjectDetail/XX/XX"];

Routable代码解析

关键方法:sharedRouter map open setNavigationController

sharedRouter方法:

//使用dispatch_once初始化单例对象 保证一个程序生命周期中使用同一个Router对象
+ (instancetype)sharedRouter {
  static Routable *_sharedRouter = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    _sharedRouter = [[Routable alloc] init];
  });
  return _sharedRouter;
}

map方法:

- (void)map:(NSString *)format toController:(Class)controllerClass withOptions:(UPRouterOptions *)options {
  if (!format) {
    @throw [NSException exceptionWithName:@"RouteNotProvided"
                                   reason:@"Route #format is not initialized"
                                 userInfo:nil];
    return;
  }
  if (!options) {
    options = [UPRouterOptions routerOptions];
  }
  options.openClass = controllerClass;
  //关键代码 创建UPRouterOptions对象 将传入的类对象作为value 参数字符串作为key存储在可变字典
  [self.routes setObject:options forKey:format];
}

setNavigationController方法:

//Router对象中有一个navigationController参数 用来保存传入的导航视图控制器 在open方法中会使用这个导航视图控制器进行跳转
@property (readwrite, nonatomic, strong) UINavigationController *navigationController;

open方法:

//调用Router类中的该方法 将传入的参数格式化成RouterParams对象
//再通过RouterParams对象从self.routes中获取对应的openClass类对象
//使用navigationController进行跳转
- (void)open:(NSString *)url
    animated:(BOOL)animated
 extraParams:(NSDictionary *)extraParams
{
  RouterParams *params = [self routerParamsForUrl:url extraParams: extraParams];
  UPRouterOptions *options = params.routerOptions;
  
  if (options.callback) {
    RouterOpenCallback callback = options.callback;
    callback([params controllerParams]);
    return;
  }
  
  if (!self.navigationController) {
    if (_ignoresExceptions) {
      return;
    }
    
    @throw [NSException exceptionWithName:@"NavigationControllerNotProvided"
                                   reason:@"Router#navigationController has not been set to a UINavigationController instance"
                                 userInfo:nil];
  }
  
  UIViewController *controller = [self controllerForRouterParams:params];
  
  if (self.navigationController.presentedViewController) {
    [self.navigationController dismissViewControllerAnimated:animated completion:nil];
  }
  
  if ([options isModal]) {
    if ([controller.class isSubclassOfClass:UINavigationController.class]) {
      [self.navigationController presentViewController:controller
                                              animated:animated
                                            completion:nil];
    }
    else {
      UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
      navigationController.modalPresentationStyle = controller.modalPresentationStyle;
      navigationController.modalTransitionStyle = controller.modalTransitionStyle;
      [self.navigationController presentViewController:navigationController
                                              animated:animated
                                            completion:nil];
    }
  }
  else if (options.shouldOpenAsRootViewController) {
    [self.navigationController setViewControllers:@[controller] animated:animated];
  }
  else {
    [self.navigationController pushViewController:controller animated:animated];
  }
}

相关文章

  • 代码解耦-iOS应用內动态跳转解决方案 Routable-iOS

    前言 在APP开发过程中,必然会遇到在WebView和推送消息中打开其他页面的需求,进一步则是在任何动态界面. 但...

  • 简单路由跳转

    当应用模块过多,各个模块可能会需要其他模块的跳转处理。模块间解耦,不需要再类中明确跳转目标的类名动态配置,业务需求...

  • iOS组件化/模块化 APP方案实践篇

    1.博客文章: [模块化与解耦](模块化与解耦 - 刘坤的技术博客) 浅析 iOS 应用组件化设计 [iOS组件化...

  • Jetpact 之 LifeCycle

    LifeCycle的诞生: 为了解决代码解耦的问题,将系统组件和普通组件尽可能的解耦 LifeCycle应用: 使...

  • ios组件化/模块化

    1.博客文章: [模块化与解耦](模块化与解耦 - 刘坤的技术博客) [浅析 iOS 应用组件化设计](Skyli...

  • ios swift URLNavigator 路由 的使用

    ios swift URLNavigator 路由 的使用 路由可以很大程度的对项目模块进行解耦;页面跳转有很多不...

  • routable-ios 源码解析

    routable-ios 是什么?可以用来做什么?与之类似的框架还有哪些? routable-ios 是一个路由框...

  • 解耦

    解耦 对于大型重构, 最有效的手段就是 解耦, 解耦的目的使实现代码高聚合、松耦合。 解耦为何如此...

  • 2022-05-01代码重构 -- 大小规模重构

    大规模高层次重构 解耦代码 “解耦”为何如此重要? 过于复杂的代码往往在可读性、可维护性上都不友好。解耦保证代码松...

  • ARouter V1.5.1 框架解析

    ARouter是阿里开源的Android路由框架,主要用于解决Android应用组件化改造解耦后组件间跳转、通信等...

网友评论

      本文标题:代码解耦-iOS应用內动态跳转解决方案 Routable-iOS

      本文链接:https://www.haomeiwen.com/subject/djgvwttx.html