iOS URL跳转组件CCRouter

2019-07-11  本文已影响0人  青年别来无恙

一、简介

CCRouter 是一个简单的iOS项目页面URL路由组件。它旨在使项目中处理复杂跳转变得简单。

CCRouter 可以很方便的处理不同 URL schemes 以及解析它们的参数,并通过回调 block 来处理 URL 对应的操作 , 是一个可以用于处理复杂跳转逻辑的三方库。

二、使用场景

1、在日常开发中,push、present 出现在整个程序的各个地方,如果你想快速理清一个项目的整体逻辑,那会非常麻烦。大多数情况 , 你得找到代码目录,根据层级结构分出关系,然后找到对应的push位置,寻找下一级页面,如果本身项目的目录就非常乱,那么如果要了解一个项目的整体跳转逻辑,将会更加困难。
如果能把整个项目的跳转逻辑都给抽取出来,单独放在一个类,模块化管理,那么思路就会清晰很多,甚至可以用 XMind 根据代码画出整个项目的树状图。
2、如果所处公司存在多个app,app之间互相推荐互相跳转是再正常不过的需求,就类似于QQ、微信、第三方分享跳转等。如果用Appdelegate 原生方法进行拦截,所做的事至少得是判断 Scheme 是否匹配,想办法进入需要跳到的界面,如果要涉及传参,就更加麻烦。
3、如果用户是从 PC端 识别二维码,或者通过链接想要进入 app 指定页面。

三、原理

本质

CCRouter 本质可以理解为:保存一个全局的字典,key 是 URL,value 是对应存放 block 的数组,URL 和 block 都会常驻在内存中,当打开一个 URL 时,CCRouter 就可以遍历这个全局的字典,通过 URL 来执行对应的 block。

- (void)registerBlock:(void (^)(NSDictionary * _Nonnull))routeHandleBlock forRoute:(NSString *)route {
    if (routeHandleBlock && route.length > 0) {
        [self.routes addObject:route];
        [self.blocksByRoute setObject:[routeHandleBlock copy] forKey:route];
    }
}

参数的解析

/**
 例如iOS://tasklist?title=任务列表&code=12
 */
- (CCRouterInfo *)routeInfo:(NSString *)fullRoute {
    CCRouterInfo *info = [[CCRouterInfo alloc] init];
    NSArray *fullParts = [fullRoute componentsSeparatedByString:@"://"];
    if (fullParts.count < 2) {
        return nil;
    }
    
    info.scheme = [fullParts firstObject];
    NSString *delimiter = @"?";
    NSArray *routePartArray = [fullRoute componentsSeparatedByString:delimiter];
    info.routePath = [routePartArray firstObject];
    if (routePartArray.count == 1) {
        info.routeParameter = @{};
        return info;
    }
    
    NSAssert(routePartArray.count > 1, @"带参Route必须包含“?”右侧参数");
    NSString *paramsString = [routePartArray objectAtIndex:1];
    delimiter = @"&";
    NSMutableDictionary *paramsDict = [NSMutableDictionary dictionary];
    NSArray *paramsPartArray = [paramsString componentsSeparatedByString:delimiter];
    delimiter = @"=";
    for (NSString *keyAndValue in paramsPartArray) {
        NSArray *keyValueArray = [keyAndValue componentsSeparatedByString:delimiter];
        NSAssert(keyValueArray.count == 2, @"参数key和value都不能为空");
        NSString *key = [keyValueArray firstObject];
        NSString *value = [keyValueArray lastObject];
        [paramsDict setObject:value forKey:key];
    }
    info.routeParameter = paramsDict;
    return info;
}

四、用法

1、pod 引入

pod 'CCRouter'

2、 注册
URL带参注册方式

[[CCRouter sharedInstance] registerBlock:^(NSDictionary *param) {
        FirstViewController *firstVC = [[FirstViewController alloc] init];
        firstVC.strTitle = param[@"title"];
        firstVC.strTips = param[@"tips"];
        UINavigationController *navc = [UIViewController currentViewController].navigationController;
        [navc pushViewController:firstVC animated:YES];
    } forRoute:@"ios://firstpage"];

单独传递参数注册方式

[[CCRouter sharedInstance] registerDictionaryParamBlock:^(NSDictionary *params) {
        SecondViewController *secondVC = [[SecondViewController alloc] init];
        secondVC.strTitle = params[@"title"];
        secondVC.strTips = params[@"tips"];
        UINavigationController *navc = [UIViewController currentViewController].navigationController;
        [navc pushViewController:secondVC animated:YES];
    } forRoute:@"ios://secondpage"];

3、调用
URL带参调用方式

[[CCRouter sharedInstance] handleRoute:@"ios://firstpage?title=url带参&tips=这是第二个参数"];

单独传递参数调用方式

NSDictionary *dict = @{
                           @"title":@"参数传递",
                           @"tips":@"这是第二个参数"
                           };
 [[CCRouter sharedInstance] handleRoute:@"ios://secondpage" parameter:dict];

支持iOS、H5、Flutter页面及外部APP的跳转

按照规定的URL规则(schame://xxx/xx?key1=value1&key2=value2
schame:用来标识跳转的页面是iOS/H5/Flutter还是外部APP

- (BOOL)isDingTalkRouter:(NSString *)route {
    return [route hasPrefix:@"dingtalk"];
}

//是APP的本地页面
- (BOOL)isiOSRoute:(NSString *)route {
    return [route hasPrefix:@"iOS:"];
}

- (BOOL)isWebRoute:(NSString*)route {
    if ([route hasPrefix:@"http"]) {
        return YES;
    } else {
        return NO;
    }
}

- (BOOL)isFlutterRoute:(NSString *)route {
    return [route hasPrefix:@"flutter"];
}

GitHub地址

上一篇下一篇

猜你喜欢

热点阅读