基于WLRRoute的移动端路由设计

本文并不是要介绍什么是移动端的路由,如果对这个概念不了解的话可以看下前人的文章,这里是 传送门
之所以决定要在项目里面加入这个机制,是源于我们运营人员的一次偶然的需求,那就是他们希望能够通过活动页的H5链接直接打开APP,并且定位到指定的页面去,当然通过传统的方式也是可以一步一步的实现,只是需要做特殊处理罢了,具体就不多说了。
但我们想做的彻底一点,不如就此机会直接加入路由好了。没错,遇到问题当你想的比别人多一两步的时候就会看到一片新的天地。目前实现的功能已经不仅仅是运营人员所提及的那个小功能了,我们已经实现了通过短信url短连接的方式访问APP页面的功能,这个功能很早之前就有了,但是我们却一直没有加入。并且对现有的代码结构也带来了好的改变,那就是我们在进行页面跳转的时候,不需要再耦合具体的视图控制器,而是通过路由进行周转,这样的话可以大大降低代码的耦合度,当然这方面目前还没有推广开,因为大伙的编码习惯是比较难改变的。如果遇到一个强有力的领 导的话,说不定会推行这件事情。
我们的路由机制是建立在WLRRoute之上的,做这个第一步就是要搞清楚什么是页面对应的url,这里的url,并不是短连接里面所显示的那样子。比如http://m.vip.com/dcf6 这个是短信里的唯品会的链接,点击后会进入到他们的M站,而在进入M站后会提示我们是否要在软件中打开,所以这里的这个地址只是连接向唯品会M站的地址而已,通过后面所携带的dcf6参数再去他们的数据库中去查询取回所对应的APP中的路由地址。这个地址通常是 URL Schemes://url这样的格式,前面的URL Schemes是每个APP所独有的,比如我们的项目的URL Schemes是 abcmanager,而我们给首页一个地址叫做homepage的话,那这个首页所对应的地址就应该是 abcmanager://homepage, 只要在访问到M站的时候,M站返回这个地址,我们就可以打开我们的软件了。当然在这之前会弹出一个确认框,让你确认是否进入APP。比如下图。

屏幕快照 2017-04-07 上午11.06.31.png

搞清楚了这个页面所对应的路由是怎么回事就好办了,接下来我们给几乎能用的到的常用页面进行了路由的url注册,将它们写入了一个plist文件中,一种是带参数的,一种是不带参数的,如下图所示。


屏幕快照 2017-04-07 上午10.50.55.png
屏幕快照 2017-04-07 上午10.50.46.png

其中pjID是那个页面所携带的参数,为0-9之间的数字。

下面简要讲一下基于WLRRoute我们所做的二次封装。
先讲一下几个关键的类:
SpaceHomeRouter,继承于WLRRouter。功能就是注册url。
SpaceHomeRouteAnalysis,继承于NSObject,用以解析外接传入的路由信息。
SpaceHomeBaseRouteHandler,继承于WLRRouteHandler,用于快速的处理handler,而无需像demo中所展示的那样每一个都创建一个类。
最后就是RouterModel,用以承载plist文件中的数据。

具体代码如下:
SpaceHomeRouter

- (id)init{
    if (self = [super init]) {
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Route" ofType:@"plist"];
        //字典数组
        NSArray *dicArray = [NSArray arrayWithContentsOfFile:filePath];
        //字典数组转化为模型数组
        _routeModelArray = [RouterModel mj_objectArrayWithKeyValuesArray:dicArray];
        _allHandlers = [NSMutableArray array];
    }
    return self;
}

- (void)registerAllHandlers{
    for (RouterModel *model in _routeModelArray) {
        SpaceHomeBaseRouteHandler *routeHandler = [SpaceHomeBaseRouteHandler routeHandlerWithClsName:model.clsName ClsTab:model.clsTabPage];
        [self registerHandler:routeHandler forRoute:[SHRouteBaseURL stringByAppendingString:model.clsUrl]];
        [_allHandlers addObject:routeHandler];
    }
}

SpaceHomeRouteAnalysis

- (void)handleURL:(NSURL *)url primitiveParameters:(NSDictionary *)primitiveParameters{
    UITabBarController *tabVC = (UITabBarController *)(AppDelegate *)[UIApplication sharedApplication].delegate.window.rootViewController;
    for (UINavigationController *nav in tabVC.viewControllers) {
        [nav popToRootViewControllerAnimated:YES];
    }
    NSLog(@"SiginCallBack");

    [[SpaceHomeRouter sharedSpaceHomeRouter] handleURL:url primitiveParameters:primitiveParameters targetCallBack:^(NSError *error, id responseObject) {
    } withCompletionBlock:^(BOOL handled, NSError *error) {
        NSLog(@"SiginHandleCompletion");
    }];
}

SpaceHomeBaseRouteHandler

+ (instancetype)routeHandlerWithClsName:(NSString *)clsName ClsTab:(NSString *)clsTab{
    return [[self alloc]initWithClsName:clsName clsTab:clsTab];
}

- (instancetype)initWithClsName:(NSString *)clsName clsTab:(NSString *)clsTab{
    if (self = [super init]) {
        _clsName = clsName;
        _clsTab = clsTab;
    }
    return self;
}

-(UIViewController *)sourceViewControllerForTransitionWithRequest:(WLRRouteRequest *)request{
    TabBarController *tabVC = (TabBarController *)[UIApplication sharedApplication].windows[0].rootViewController;
    CommonNavigationViewController *nav = (CommonNavigationViewController *)tabVC.selectedViewController;
    return nav;
}

-(UIViewController *)targetViewControllerWithRequest:(WLRRouteRequest *)request{    
    UIViewController * vc = [[NSClassFromString(_clsName) alloc]init];
    return vc;
}

-(BOOL)transitionWithWithRequest:(WLRRouteRequest *)request sourceViewController:(UIViewController *)sourceViewController targetViewController:(UIViewController *)targetViewController isPreferModal:(BOOL)isPreferModal error:(NSError *__autoreleasing *)error{
    if (_clsTab.intValue>0) {
        TabBarController *tabVC = (TabBarController *)[UIApplication sharedApplication].windows[0].rootViewController;
        tabVC.selectedIndex = _clsTab.intValue-1;
        return YES;
    }
    
    if (isPreferModal||![sourceViewController isKindOfClass:[CommonNavigationViewController class]]) {
        [sourceViewController presentViewController:targetViewController animated:YES completion:nil];
    }
    else if ([sourceViewController isKindOfClass:[CommonNavigationViewController class]]){
        CommonNavigationViewController * nav = (CommonNavigationViewController *)sourceViewController;
        [nav pushViewController:targetViewController animated:YES];
    }
    return YES;
}

最后在Appdelegate中的方法中加入下面一句代码就可以了。

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
    [[SpaceHomeRouteAnalysis sharedSpaceHomeRouteAnalysis]handleURL:url primitiveParameters:options];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容