移动开发 \ iOS \ iOS路由跳转(五)之JKRouter 2.0 脱胎换骨

iOS路由跳转(五)之JKRouter 2.0 脱胎换骨

总点击151
简介:  经过一段时间的使用,以及对于需求的复杂化,JKRouter暴露出来了很多的问题。下面我就会将这些问题一一列出来。

  经过一段时间的使用,以及对于需求的复杂化,JKRouter暴露出来了很多的问题。下面我就会将这些问题一一列出来。


1,不能够使用xib,storyboard文件的跳转。


由于JKRouter使用了kvc赋值以及目标UIViewController对象的创建是通过[NClassFromString(vcCalssName) new],但是xib,storyboard的ViewController却无法通过这种方式进行初始化。所以在JKRouter 2.0 中在UIViewController+JKRouter.h 这个category中新增加了一个方法。

+ (instancetype)jkRouterViewController{

return [[[self class] alloc] init];

}

对于不需要通过storyboard,xib初始化的ViewController,可以直接使用+ (instancetype)jkRouterViewController 进行初始化。但是使用storyboard进行创建的viewController,我们可以对该方法进行重写。代码如下:

+ (instancetype)jkRouterViewController{

UIStoryboard *mainStory = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

JKFViewController *fVC = [mainStory instantiateViewControllerWithIdentifier:@"JKFViewController"];

return fVC;

}

这个方法在组件化下路径会有所变更,希望大家注意哦。

2,对于自定义的转场方式支持度不够。


由于之前项目中用到的自定义转场方式不多,JKRouter只支持系统的present和push。对自定义的转场动画支持不足。为了解决问题。这里定义了:

typedef NS_ENUM(NSInteger,RouterTransformVCStyle){///< ViewController的转场方式

RouterTransformVCStyleDefault =-1,///< 不指定转场方式,使用自带的转场方式

RouterTransformVCStylePush,///< push方式转场

RouterTransformVCStylePresent,///< present方式转场

RouterTransformVCStyleOther ///< 用户自定义方式转场

};

在UIViewController+JKRouter.h 中


- (RouterTransformVCStyle)jkRouterTransformStyle{


return RouterTransformVCStylePush;


}


默认是push的转场方式,如果是想要实现自定义的转场方式,那么需要相关的viewController 重写- (RouterTransformVCStyle)jkRouterTransformStyle 方法,并且返回RouterTransformVCStyleOther。同时重写- (void)jkRouterSpecialTransformWithNaVC:(UINavigationController *)naVC 方法,实现自定义的转场方式。


3,对自定义协议支持度不够。


之前虽然实现了自定义协议的支持,但是对于h5,native模块的跳转区分没有进行系统的 规划是通过moduleID的范围来划分的,不够完美。实用性,普遍性都不够好。这次对代码进行了调整,可以实现自动的区分h5和native模块。具体如下:

+ (void)URLOpen:(NSString *)url params:(NSDictionary *)params{

url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSURL *targetURL = [NSURL URLWithString:url];

NSString *scheme =targetURL.scheme;

if (![[JKRouter router].urlSchemes containsObject:scheme]) {

return;

}

if (![JKRouterExtension safeValidateURL:url]) {

return;

}

if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) {

[self httpOpen:targetURL];

return;

}

//URL的端口号作为moduleID

NSNumber *moduleID = targetURL.port;

if (moduleID) {

NSString *homePath = [JKJSONHandler getHomePathWithModuleID:moduleID];

if ([NSClassFromString(homePath) isSubclassOfClass:[UIViewController class]]) {

NSString *parameterStr = [[targetURL query] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSMutableDictionary *dic = nil;

if (JKSafeStr(parameterStr)) {

dic = [self convertUrlStringToDictionary:parameterStr];

[dic addEntriesFromDictionary:params];

}else{

dic = [NSMutableDictionary dictionaryWithDictionary:params];

}

NSString *vcClassName = homePath;

RouterOptions *options = [RouterOptions optionsWithModuleID:[NSString stringWithFormat:@"%@",moduleID]];

options.defaultParams = [dic copy];

//执行页面的跳转

[self open:(NSString *)vcClassName options:options];

}else{

NSString *subPath = targetURL.resourceSpecifier;

NSString *path = [NSString stringWithFormat:@"%@/%@",homePath,subPath];

RouterOptions *options = [RouterOptions optionsWithModuleID:[NSString stringWithFormat:@"%@",moduleID]];

[self jumpToHttpWeb:path options:options];

}

}else{

NSString *path = targetURL.path;

if ([NSClassFromString(path) isKindOfClass:[UIViewController class]]) {

NSString *parameterStr = [[targetURL query] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSMutableDictionary *dic = nil;

if (JKSafeStr(parameterStr)) {

dic = [self convertUrlStringToDictionary:parameterStr];

[dic addEntriesFromDictionary:params];

}else{

dic = [NSMutableDictionary dictionaryWithDictionary:params];

}

NSString *vcClassName = path;

RouterOptions *options = [RouterOptions optionsWithModuleID:[NSString stringWithFormat:@"%@",moduleID]];

options.defaultParams = [dic copy];

//执行页面的跳转

[self open:(NSString *)vcClassName options:options];

}else{

RouterOptions *options = [RouterOptions optionsWithModuleID:[NSString stringWithFormat:@"%@",moduleID]];

[self jumpToHttpWeb:path options:options];

}

}

}

4,对于是否app内打开,还是safari打开无法做到自动识别。


针对着种情况,通过在url中携带相关参数,并对参数进行解析,来实现相关的两种打开方式的区分。具体代码如下:


+ (void)httpOpen:(NSURL *)targetURL{


NSString *parameterStr = [[targetURL query] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

if (JKSafeStr(parameterStr)) {

NSMutableDictionary *dic = [self convertUrlStringToDictionary:parameterStr];

NSDictionary *params = [dic copy];

if (JKSafeDic(params) && [[params objectForKey:JKRouterHttpOpenStyleKey] isEqualToString:@"1"]) {//判断是否是在app内部打开网页

RouterOptions *options = [RouterOptions options];

[self jumpToHttpWeb:targetURL.absoluteString options:options];

return;

}

}

[self openExternal:targetURL];

}

主要是判断url是否有 JKRouterHttpOpenStyleKey 对应的参数,且参数为1。


5,权限等级判定通用性差


之前使用在对权限等级进行判定处理的时候,是事先通过宏定义,然后通过路由文件进行配置,这种方法比较麻烦,通用性差,对每一个页面都需要配置。使用起来非常的不方便。在JKRouter 2.0 中直接通过UIViewController category的两个方法

+ (BOOL)validateTheAccessToOpen{

return YES;

}

+ (void)handleNoAccessToOpen{

}

可以在当前页面对是否具有权限进行实时的判断,省去了路由配置的环节,可操作性更强。

源码地址:https://github.com/xindizhiyin2014/JKRouter

往期文章:


iOS路由跳转(一)之初识URL


iOS路由跳转(二)之需求分析


iOS路由跳转(三)之JKRouter基础教程1


iOS路由跳转(四)之JKRouter持续更新1

QQ交流群:扫码入群


iOS路由跳转(五)之JKRouter 2.0 脱胎换骨

意见反馈 常见问题 官方微信 返回顶部