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

前言

在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简单使用)