一个高效/灵活的 iOS URL Router
有些场景我们可能需要根据 URL 获取某个 Object,所以就添加了这个方法
UIView *searchTopBar = [MGJRouter objectForURL:@"search_top_bar"];
已经有几款不错的 Router 了,如 JLRoutes, HHRouter, 但细看了下之后发现,还是不太满足需求。
JLRoutes 的问题主要在于查找 URL 的实现不够高效,通过遍历而不是匹配。还有就是功能偏多。
HHRouter 的 URL 查找是基于匹配,所以会更高效,MGJRouter 也是采用的这种方法,但它跟 ViewController 绑定地过于紧密,一定程度上降低了灵活性。
于是就有了 MGJRouter。
pod 'MGJRouter', '~>0.9.0'
[MGJRouter registerURLPattern:@"mgj:https://foo/bar" toHandler:^(NSDictionary *routerParameters) {
NSLog(@"routerParameterUserInfo:%@", routerParameters[MGJRouterParameterUserInfo]);
}];
[MGJRouter openURL:@"mgj:https://foo/bar"];
当匹配到 URL 后,routerParameters
会自带几个 key
extern NSString *const MGJRouterParameterURL;
extern NSString *const MGJRouterParameterCompletion;
extern NSString *const MGJRouterParameterUserInfo;
[MGJRouter registerURLPattern:@"mgj:https://category/家居" toHandler:^(NSDictionary *routerParameters) {
NSLog(@"routerParameters:%@", routerParameters);
}];
[MGJRouter openURL:@"mgj:https://category/家居"];
[MGJRouter registerURLPattern:@"mgj:https://category/travel" toHandler:^(NSDictionary *routerParameters) {
NSLog(@"routerParameters[MGJRouterParameterUserInfo]:%@", routerParameters[MGJRouterParameterUserInfo]);
// @{@"user_id": @1900}
}];
[MGJRouter openURL:@"mgj:https://category/travel" withUserInfo:@{@"user_id": @1900} completion:nil];
[MGJRouter registerURLPattern:@"mgj:https://search/:query" toHandler:^(NSDictionary *routerParameters) {
NSLog(@"routerParameters[query]:%@", routerParameters[@"query"]); // bicycle
NSLog(@"routerParameters[color]:%@", routerParameters[@"color"]); // red
}];
[MGJRouter openURL:@"mgj:https://search/bicycle?color=red"];
[MGJRouter registerURLPattern:@"mgj:https://" toHandler:^(NSDictionary *routerParameters) {
NSLog(@"没有人处理该 URL,就只能 fallback 到这里了");
}];
[MGJRouter openURL:@"mgj:https://search/travel/china?has_travelled=0"];
[MGJRouter registerURLPattern:@"mgj:https://detail" toHandler:^(NSDictionary *routerParameters) {
NSLog(@"匹配到了 url, 一会会执行 Completion Block");
// 模拟 push 一个 VC
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
void (^completion)() = routerParameters[MGJRouterParameterCompletion];
if (completion) {
completion();
}
});
}];
[MGJRouter openURL:@"mgj:https://detail" withUserInfo:nil completion:^{
[self appendLog:@"Open 结束,我是 Completion Block"];
}];
URL 的处理一不小心,就容易散落在项目的各个角落,不容易管理。比如注册时的 pattern 是 mgj:https://beauty/:id
,然后 open 时就是 mgj:https://beauty/123
,这样到时候 url 有改动,处理起来就会很麻烦,不好统一管理。
所以 MGJRouter 提供了一个类方法来处理这个问题。
+ (NSString *)generateURLWithPattern:(NSString *)pattern parameters:(NSArray *)parameters;
使用方式
#define TEMPLATE_URL @"mgj:https://search/:keyword"
[MGJRouter registerURLPattern:TEMPLATE_URL toHandler:^(NSDictionary *routerParameters) {
NSLog(@"routerParameters[keyword]:%@", routerParameters[@"keyword"]); // Hangzhou
}];
[MGJRouter openURL:[MGJRouter generateURLWithPattern:TEMPLATE_URL parameters:@[@"Hangzhou"]]];
}
这样就可以在一个地方定义所有的 URL Pattern,使用时,用这个方法生成 URL 就行了。
MGJRouter 被许可在 MIT 协议下使用。查阅 LICENSE 文件来获得更多信息。