JKRouter经历多次迭代版本终于稳定了,为了方便大家接入使用,我特意写了这篇文章。之前没有了解过JKRouter的小伙伴可以先看看这连篇博客《iOS路由跳转(二)之需求分析》《JKRouter路由跳转解决了哪些问题》。

1,JKRouter接入

在项目中创建podfile文件,将pod "JKRouter"复制到podfile中,然后执行pod install就可以了。注:(建议从ios8之后的小伙伴使用哦,iOS 7有些功能可能会不支持)。

2,JKRouter支持的rootViewController配置

在如下方法内配置JKRouter

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

这里有两种配置方案,具体如下。

1)方案一
self.rootTabBarController = [[RootTabbarViewController alloc] init];
 
 UINavigationController *naVC = [[UINavigationController alloc] initWithRootViewController: self.rootTabBarController];
 self.window.rootViewController = naVC;
 [JKRouter router].windowRootVCStyle = RouterWindowRootVCStyleDefault;
 
 或者:
 UIViewController *vc = [UIViewController new];
 UINavigationController *naVC = [[UINavigationController alloc] initWithRootViewController:vc];
 self.window.rootViewController = naVC;
 [JKRouter router].windowRootVCStyle = RouterWindowRootVCStyleDefault;
2)方案二
UIViewController *vc1 = [UIViewController new];
 UINavigationController *naVC = [[UINavigationController alloc] initWithRootViewController:vc1];
 UIViewController *vc2 = [UIViewController new];
 UINavigationController *naVC1 = [[UINavigationController alloc] initWithRootViewController:vc2];
 UIViewController *vc3 = [UIViewController new];
 UINavigationController *naVC2 = [[UINavigationController alloc] initWithRootViewController:vc3];
 UITabBarController *tabBarVC3 = [UITabBarController new];
 tabBarVC.viewControllers = @[naVC1,naVC2,naVC3];
 self.window.rootViewController = tabBarVC.viewControllers;
 [JKRouter router].windowRootVCStyle = RouterWindowRootVCStyleCustom;

3,JKRouter配置路由信息文件。

[JKRouter configWithRouterFiles:@[@"modules.json",@"modules123.json"]];
//这里之所以支持以数组的形式配置json文件,主要是在实际的开发过程中,可能存在native小伙伴的路由配置,和h5小伙伴的路由配置文件。为了便于维护,双方给自维护自己的路由表文件

如果写的有路由文件下发接口的,可以使用下面这个方法,进行配置。

/**
 更新路由信息

 @param filePath 路由配置信息的文件在沙盒中的路径
 */
+ (void)updateRouterInfoWithFilePath:(NSString*)filePath;

注:更新后,router的路由配置信息以网络下载的json文件信息为准,app目录下的json文件失效。具体的逻辑开发的小伙伴可以做一下相关的逻辑处理,什么时候使用app目录下的json文件,什么时候使用网络下载的json文件。
##4,配置JKJSONHandler
通过创建JKJSONHandler的category文件对路由文件进行自定义解析,代码如下

+ (NSString *)getHomePathWithModuleID:(NSString *)moduleID{
    
    NSString *vcClassName = nil;
    for (NSDictionary *module in [JKRouter router].modules) {
        NSString *tempModuleID =[NSString stringWithFormat:@"%@",module[@"moduleID"]];
        if ([tempModuleID isEqualToString:moduleID]) {
            vcClassName = module[@"targetVC"];
            break;
        }
    }
    return vcClassName;
}

+ (NSString *)getTypeWithModuleID:(NSString *)moduleID{
    NSString *type = nil;
    for (NSDictionary *module in [JKRouter router].modules) {
        NSString *tempModuleID =[NSString stringWithFormat:@"%@",module[@"moduleID"]];
        if ([tempModuleID isEqualToString:moduleID]) {
            type = module[@"type"];
            break;
        }
    }
    return type;
}

示例json文件配置如下:

[
  {
  "moduleID":"user_profile",
  "type":"ViewController",
  "targetVC":"JKBViewController",
  "desc":"用户主页"
  },
  {
  "moduleID":"apply_invite_code",
  "type":"ViewController",
  "targetVC":"JKDViewController",
  "desc":"邀请码"
  },
  {
  "moduleID":"wallet",
  "type":"ViewController",
  "targetVC":"JKWebViewController",
  "desc":"钱包流水 无参数"
  }
  ]

5,url安全校验

  JKRouter路由跳转的url安全校验,主要通过几个方面进行校验。

1)配置url的scheme

通过创建JKRouterExtension的category文件对urlSchemes

+ (NSArray *)urlSchemes{
    return @[@"http",
             @"https",
             @"file",
             @"itms-apps"];
    
}

进行重写添加app支持的协议,其他协议的url就会被禁止跳转。

2)对url内容进行安全性校验

通过对JKRouterExtension中下面这个函数

+ (BOOL)safeValidateURL:(NSString *)url{
    //默认都是通过安全性校验的
    return YES;
}

的重写,对url的内容进行安全性校验,我们可以限制url的长度,url中是否有特殊字符。验证的规则很多,具体可以根据实际需求。

6,配置web容器

在app的开发过程中,我们经常会用一个公共的webViewController来打开常见的url,在这里JKRouter配置如下:

1)配置web容器的类名
/**
 配置web容器从外部获取url的property的字段名
 
 @return property的字段名
 */
+ (NSString *)jkWebURLKey;

/**
 配置webVC的className,使用的时候可以通过category重写方法配置

 @return webVC的className
 */
+ (NSArray *)jkWebVCClassNames{
    return nil;
}

+ (NSString *)jkWebURLKey{
    
    return @"jkurl";
}

+ (NSString *)jkWebVCClassName{
    return @"";
}

通过重写这两个方法设置jkWebURLKey和jkWebVCClassNames后,就可以使用用户自己自定义歌的webViewController了

7,viewController的初始化以及赋值操作。

/**
 初始化viewController对象,可以重写该方法的实现,进行viewController的初始化。默认返回不为空

 @return 初始化后的viewController对象
 */
+ (instancetype)jkRouterViewController;

/**
 初始化viewController对象,默认返回为空,可以重写该方法实现初始化。赋值操作可以通过YYModel,或者别的工具类在内部实现。该方法主要用于h5和native交互跳转时,需要传输大量参数赋值时调用,或者后台接口返回的数据实现页面跳转时使用。

 @param dic json对象。纯数据的,内部不含OC对象
 @return 初始化后,赋值完成的viewController对象
 */
+ (instancetype)jkRouterViewControllerWithJSON:(NSDictionary *)dic;
+ (instancetype)jkRouterViewController{
    return [[[self class] alloc] init];
}

+ (instancetype)jkRouterViewControllerWithJSON:(NSDictionary *)dic{
    return nil;
}

具体在开发的过程中可以对这两个方法进行重写,尤其是第二个方法可以结合YYModel进行赋值操作。示例代码如下

+ (instancetype)jkRouterViewControllerWithJSON:(NSDictionary *)dic{
    WWBaseViewController *vc = [self yy_modelWithJSON:dic];//使用YYModel的代码
    if (![self jkIsTabBarItemVC]) {
        vc.hidesBottomBarWhenPushed =YES;
    }else{
        vc.hidesBottomBarWhenPushed =NO;
    }
    return vc;
}

+ (instancetype)jkRouterViewController{
    WWBaseViewController *vc = [[[self class] alloc] init];
    if (![self jkIsTabBarItemVC]) {
        vc.hidesBottomBarWhenPushed =YES;
    }else{
        vc.hidesBottomBarWhenPushed =NO;
    }
    return vc;
}

8,权限等级的判定处理

对于页面打开权限等级的判定处理,这里UIViewController+JKRouter中有两个方法,一个是判定权限的,一个是权限不够时的异常处理。代码如下

+ (BOOL)validateTheAccessToOpenWithOptions:(RouterOptions *)options{
    return YES;
}

+ (void)handleNoAccessToOpenWithOptions:(RouterOptions *)options{
}

具体在开发过程中,可以根据实际情况对上面两个方法进行重写。

9,实现自定义转场动画

- (void)jkRouterSpecialTransformWithNaVC:(UINavigationController *)naVC{
}

- (RouterTransformVCStyle)jkRouterTransformStyle{
    return RouterTransformVCStyleOther;
}

要实现自定义的转场动画,我们可以设置jkRouterTransformStyleRouterTransformVCStyleOther

10,url打开弹框,actionsheet

使用JKRouter时,url如果要打开弹框,actionSheet时,需要对JKRouterExtension中

/**
 除了路由跳转以外的操作
 @param actionType 操作的类型
 @param url url
 @param extra 额外传入的参数
 @param completeBlock 操作成功后的回调
 
 */
+ (void)otherActionsWithActionType:(NSString *)actionType URL:(NSURL *)url extra:(NSDictionary *)extra complete:(void(^)(id result,NSError *error))completeBlock

进行重写。
经过了上面种种的配置,就可以很愉快的使用JKRouter了,当然了由于JKrouter功能的强大,很多小伙伴不一定都要进行配置。有的只需要配置一部分就好了。
后面我们就可以使用下面的方法进行open和pop操作了。

/**
 默认打开方式
 一般由native调用
 @param vcClassName 跳转的控制器类名
 */
+ (void)open:(NSString *)vcClassName;


/**
 根据options的设置进行跳转
 
 @param vcClassName 跳转的控制器类名
 @param options 跳转的各种设置
 */
+ (void)open:(NSString *)vcClassName options:(RouterOptions *)options;

/**
 主要是通过后台,或者H5交互是携带json参数进行跳转,对应的ViewController内部需要实现
+ (instancetype)jkRouterViewControllerWithJSON:(NSDictionary *)dic 这个方法的重写。
 @param vcClassName 跳转的控制器类名
 @param options 跳转的各种设置 options 的defaultParams 是json对象。内部value不能是OC的对象
 */
+ (void)open:(NSString *)vcClassName optionsWithJSON:(RouterOptions *)options;
/**
 根据options和已有的vc进行跳转

 @param vc 已经创建的指定的vc
 @param options 跳转的各种设置
 */
+ (void)openSpecifiedVC:(UIViewController *)vc options:(RouterOptions *)options;

/**
 根据options的设置进行跳转,并执行相关的回调操作

 @param vcClassName 跳转的控制器类名
 @param options 跳转的各种设置
 @param callback 回调
 */
+ (void)open:(NSString *)vcClassName options:(RouterOptions *)options CallBack:(void(^)(void))callback;


/**
 遵守用户指定协议的跳转
 在外部浏览器唤醒app,H5调用相关模块时使用
 适用于携带少量参数,不带参数的跳转
 @param url 跳转的路由 携带参数
 */
+ (void)URLOpen:(NSString *)url;


/**
 遵守用户指定协议的跳转

 适用于携带大量参数的跳转,多用于H5页面跳转到native页面
 @param url 跳转的路由,不携带参数
 @param extra 额外传入的参数
 */
+ (void)URLOpen:(NSString *)url extra:(NSDictionary *)extra;

/**
 遵守用户指定协议的跳转
 
 适用于携带大量参数的跳转,多用于H5页面跳转到native页面
 @param url 跳转的路由,不携带参数
 @param extra 额外传入的参数
 @param completeBlock 跳转成功后的回调
 */
+ (void)URLOpen:(NSString *)url extra:(NSDictionary *)extra complete:(void(^)(id result,NSError *error))completeBlock;

/**
 适用于访问基于http协议/https协议的路由跳转

 @param url 跳转的路由,可以携带少量参数
 */
+ (void)httpOpen:(NSURL *)url;

/**
 默认情况下的pop,或者dismiss ,animated:YES
 */
+ (void)pop;

/**
 默认情况下的pop,或者dismiss,animated:YES

 @param animated 是否有动画
 */
+ (void)pop:(BOOL)animated;


/**
 默认情况下的pop,或者dismiss animated

 @param params 返回时携带的参数
 @param animated 是否有动画
 */
+ (void)pop:(NSDictionary *)params :(BOOL)animated;

/**
 pop到指定的页面
默认animated为YES,如果需要 dismiss,也会执行
 @param vc 指定的vc对象
 */
+ (void)popToSpecifiedVC:(UIViewController *)vc;

/**
 pop到指定的页面
 如果需要 dismiss,也会执行
 @param vc 指定的vc对象
 @param animated 是否有动画
 */
+ (void)popToSpecifiedVC:(UIViewController *)vc animated:(BOOL)animated;

/**
 根据moduleID pop回指定的模块

 @param moduleID 指定要返回的moduleID
 */
+ (void)popWithSpecifiedModuleID:(NSString *)moduleID;


/**
  根据moduleID pop回指定的模块
 并指定动画模式
 @param moduleID 指定要返回的moduleID
 @param params 返回时携带的参数
 @param animated 是否有动画
 */
+ (void)popWithSpecifiedModuleID:(NSString *)moduleID :(NSDictionary *)params :(BOOL)animated;

/**
 根据step的值pop向前回退几个VC
 如果step大于当前当前naVC.viewController.count,时返回pop to rootViewController
 @param step 回退的vc的数量
 */
+ (void)popWithStep:(NSInteger)step;

/**
 根据step的值pop向前回退几个VC
 如果step大于当前当前naVC.viewController.count,时返回pop to rootViewController
 
 @param step 回退的vc的数量
 @param animated 是否有动画效果
 */
+ (void)popWithStep:(NSInteger)step :(BOOL)animated;

/**
 根据step的值pop向前回退几个VC
 如果step大于当前当前naVC.viewController.count,时返回pop to rootViewController
 
 @param step 回退的vc的数量
 @param params 返回时传递的参数
 @param animated 是否有动画效果
 */
+ (void)popWithStep:(NSInteger)step params:(NSDictionary *)params animated:(BOOL)animated;


/**
 通过浏览器跳转到相关的url或者唤醒相关的app

 @param targetURL 路由信息
 */
+ (void)openExternal:(NSURL *)targetURL;


/**
 使用targetVC替换navigattionController当前的viewController

 @param targetVC 目标viewController
 */
+ (void)replaceCurrentViewControllerWithTargetVC:(UIViewController *)targetVC;