基于WLRRoute的移動(dòng)端路由設(shè)計(jì)

本文并不是要介紹什么是移動(dòng)端的路由,如果對(duì)這個(gè)概念不了解的話可以看下前人的文章,這里是 傳送門。
之所以決定要在項(xiàng)目里面加入這個(gè)機(jī)制,是源于我們運(yùn)營人員的一次偶然的需求,那就是他們希望能夠通過活動(dòng)頁的H5鏈接直接打開APP,并且定位到指定的頁面去,當(dāng)然通過傳統(tǒng)的方式也是可以一步一步的實(shí)現(xiàn),只是需要做特殊處理罷了,具體就不多說了。
但我們想做的徹底一點(diǎn),不如就此機(jī)會(huì)直接加入路由好了。沒錯(cuò),遇到問題當(dāng)你想的比別人多一兩步的時(shí)候就會(huì)看到一片新的天地。目前實(shí)現(xiàn)的功能已經(jīng)不僅僅是運(yùn)營人員所提及的那個(gè)小功能了,我們已經(jīng)實(shí)現(xiàn)了通過短信url短連接的方式訪問APP頁面的功能,這個(gè)功能很早之前就有了,但是我們卻一直沒有加入。并且對(duì)現(xiàn)有的代碼結(jié)構(gòu)也帶來了好的改變,那就是我們?cè)谶M(jìn)行頁面跳轉(zhuǎn)的時(shí)候,不需要再耦合具體的視圖控制器,而是通過路由進(jìn)行周轉(zhuǎn),這樣的話可以大大降低代碼的耦合度,當(dāng)然這方面目前還沒有推廣開,因?yàn)榇蠡锏木幋a習(xí)慣是比較難改變的。如果遇到一個(gè)強(qiáng)有力的領(lǐng) 導(dǎo)的話,說不定會(huì)推行這件事情。
我們的路由機(jī)制是建立在WLRRoute之上的,做這個(gè)第一步就是要搞清楚什么是頁面對(duì)應(yīng)的url,這里的url,并不是短連接里面所顯示的那樣子。比如http://m.vip.com/dcf6 這個(gè)是短信里的唯品會(huì)的鏈接,點(diǎn)擊后會(huì)進(jìn)入到他們的M站,而在進(jìn)入M站后會(huì)提示我們是否要在軟件中打開,所以這里的這個(gè)地址只是連接向唯品會(huì)M站的地址而已,通過后面所攜帶的dcf6參數(shù)再去他們的數(shù)據(jù)庫中去查詢?nèi)』厮鶎?duì)應(yīng)的APP中的路由地址。這個(gè)地址通常是 URL Schemes://url這樣的格式,前面的URL Schemes是每個(gè)APP所獨(dú)有的,比如我們的項(xiàng)目的URL Schemes是 abcmanager,而我們給首頁一個(gè)地址叫做homepage的話,那這個(gè)首頁所對(duì)應(yīng)的地址就應(yīng)該是 abcmanager://homepage, 只要在訪問到M站的時(shí)候,M站返回這個(gè)地址,我們就可以打開我們的軟件了。當(dāng)然在這之前會(huì)彈出一個(gè)確認(rèn)框,讓你確認(rèn)是否進(jìn)入APP。比如下圖。

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

搞清楚了這個(gè)頁面所對(duì)應(yīng)的路由是怎么回事就好辦了,接下來我們給幾乎能用的到的常用頁面進(jìn)行了路由的url注冊(cè),將它們寫入了一個(gè)plist文件中,一種是帶參數(shù)的,一種是不帶參數(shù)的,如下圖所示。


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

其中pjID是那個(gè)頁面所攜帶的參數(shù),為0-9之間的數(shù)字。

下面簡(jiǎn)要講一下基于WLRRoute我們所做的二次封裝。
先講一下幾個(gè)關(guān)鍵的類:
SpaceHomeRouter,繼承于WLRRouter。功能就是注冊(cè)u(píng)rl。
SpaceHomeRouteAnalysis,繼承于NSObject,用以解析外接傳入的路由信息。
SpaceHomeBaseRouteHandler,繼承于WLRRouteHandler,用于快速的處理handler,而無需像demo中所展示的那樣每一個(gè)都創(chuàng)建一個(gè)類。
最后就是RouterModel,用以承載plist文件中的數(shù)據(jù)。

具體代碼如下:
SpaceHomeRouter

- (id)init{
    if (self = [super init]) {
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Route" ofType:@"plist"];
        //字典數(shù)組
        NSArray *dicArray = [NSArray arrayWithContentsOfFile:filePath];
        //字典數(shù)組轉(zhuǎn)化為模型數(shù)組
        _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];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,711評(píng)論 19 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,355評(píng)論 25 708
  • 前言 隨著用戶的需求越來越多,對(duì)App的用戶體驗(yàn)也變的要求越來越高。為了更好的應(yīng)對(duì)各種需求,開發(fā)人員從軟件工程的角...
    一縷殤流化隱半邊冰霜閱讀 88,186評(píng)論 214 1,098
  • 什么是移動(dòng)端路由層: 路由層的概念在服務(wù)端是指url請(qǐng)求的分層解析,將一個(gè)請(qǐng)求分發(fā)到對(duì)應(yīng)的應(yīng)用處理程序。移動(dòng)端的路...
    Neo_joke閱讀 15,129評(píng)論 11 124
  • 綠松石作為一種顏色嬌艷的玉石,其價(jià)格近年來一直上漲,作為一種收藏品,綠松石未來的潛力不可低估。但是綠松石的收藏也是...
    五柳文玩華掌柜閱讀 279評(píng)論 0 0

友情鏈接更多精彩內(nèi)容