JLRoutes 是一个基于简单块操作的 URL 路由库。它旨在通过最少的代码,使处理应用中的复杂 URL 方案变得非常容易。
JLRoutes 可通过 CocoaPods 或 Carthage 安装(将 github "joeldev/JLRoutes"
添加到 Cartfile
)。
JLRoutes 2.x 需要 iOS 8.0+ 或 macOS 10.10+。如果您需要支持 iOS 7 或 macOS 10.9,请使用版本 1.6.4(这是最后一个 1.x 版本)。
文档可在以下位置找到:此处。
// in your app delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ...
JLRoutes *routes = [JLRoutes globalRoutes];
[routes addRoute:@"/user/view/:userID" handler:^BOOL(NSDictionary *parameters) {
NSString *userID = parameters[@"userID"]; // defined in the route by specifying ":userID"
// present UI for viewing user with ID 'userID'
return YES; // return YES to say we have handled the route
}];
// ...
return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options
{
return [JLRoutes routeURL:url];
}
路由还可以使用索引符号语法进行注册
JLRoutes.globalRoutes[@"/route/:param"] = ^BOOL(NSDictionary *parameters) {
// ...
};
在设置好此路由后,任何时间点(包括其他应用)都可以调用此方法来触发处理块
NSURL *viewUserURL = [NSURL URLWithString:@"myapp://user/view/joeldev"];
[[UIApplication sharedApplication] openURL:viewUserURL];
在此示例中,传递给块的参数字典中的 userID 对象将具有以下键/值对 "userID": "joeldev"
,可以使用此信息显示 UI 或执行其他操作。
参数字典通常至少包含以下三个键
{
"JLRouteURL": "(the NSURL that caused this block to be fired)",
"JLRoutePattern": "(the actual route pattern string)",
"JLRouteScheme": "(the route scheme, defaults to JLRoutesGlobalRoutesScheme)"
}
JLRouteScheme 键表示匹配的路由所在的方案。有关方案的信息,请参阅 此处。
有关常量的列表,请参阅 JLRoutes.h。
如您所注意到的,处理块期望返回一个布尔值,表示是否已处理路由。如果块返回 NO
,JLRoutes 将表现得好像该路由不匹配,并继续寻找匹配项。只有当模式字符串匹配并且块返回 YES
时,才认为路由匹配。
值得注意的是,如果您为处理器块传递nil,则会创建一个返回YES
的内部处理器块。
[[JLRoutes globalRoutes] addRoute:@"/:object/:action/:primaryKey" handler:^BOOL(NSDictionary *parameters) {
NSString *object = parameters[@"object"];
NSString *action = parameters[@"action"];
NSString *primaryKey = parameters[@"primaryKey"];
// stuff
return YES;
}];
这条路由将匹配诸如/user/view/joeldev
或/post/edit/123
之类的URL路径。假设您以某些URL参数调用了/post/edit/123
NSURL *editPost = [NSURL URLWithString:@"myapp://post/edit/123?debug=true&foo=bar"];
[[UIApplication sharedApplication] openURL:editPost];
处理器块接收的参数字典将包含以下键值对
{
"object": "post",
"action": "edit",
"primaryKey": "123",
"debug": "true",
"foo": "bar",
"JLRouteURL": "myapp://post/edit/123?debug=true&foo=bar",
"JLRoutePattern": "/:object/:action/:primaryKey",
"JLRouteScheme": "JLRoutesGlobalRoutesScheme"
}
JLRoutes支持在特定URL方案内设置路由。设置在方案内的路由只能由使用匹配URL方案的URL进行匹配。默认情况下,所有路由都进入全局方案。
[[JLRoutes globalRoutes] addRoute:@"/foo" handler:^BOOL(NSDictionary *parameters) {
// This block is called if the scheme is not 'thing' or 'stuff' (see below)
return YES;
}];
[[JLRoutes routesForScheme:@"thing"] addRoute:@"/foo" handler:^BOOL(NSDictionary *parameters) {
// This block is called for thing://foo
return YES;
}];
[[JLRoutes routesForScheme:@"stuff"] addRoute:@"/foo" handler:^BOOL(NSDictionary *parameters) {
// This block is called for stuff://foo
return YES;
}];
此示例显示您可以在不同的方案中声明相同的路由,并根据每个方案使用不同的回调来处理它们。
在此基础上,如果您要添加以下路由
[[JLRoutes globalRoutes] addRoute:@"/global" handler:^BOOL(NSDictionary *parameters) {
return YES;
}];
然后尝试将URLthing://global
路由,它不会匹配,因为该路由没有在thing
方案中声明,而是在全局方案中声明(我们假设这是开发人员想要的)。但是,您可以轻松地通过将该属性设置为YES
来更改此行为
[JLRoutes routesForScheme:@"thing"].shouldFallbackToGlobalRoutes = YES;
这告诉JLRoutes,如果在thing
方案(即,以thing:
开头但没有找到适当的路由)内无法将URL进行路由,则尝试在全球路由方案中寻找匹配的路由。将该属性设置为YES
后,URLthing://global
将被路由到/global块。
JLRoutes支持设置将匹配路由URL末尾任意数量路径组件的路由。将包含额外路径组件的数组添加到参数字典中,键为JLRouteWildcardComponentsKey
。
例如,以下路由将针对任何以/wildcard/
开始的URL触发,但如果下一组件不是joker
,则会被处理器拒绝。
[[JLRoutes globalRoutes] addRoute:@"/wildcard/*" handler:^BOOL(NSDictionary *parameters) {
NSArray *pathComponents = parameters[JLRouteWildcardComponentsKey];
if ([pathComponents count] > 0 && [pathComponents[0] isEqualToString:@"joker"]) {
// the route matched; do stuff
return YES;
}
// not interested unless the joker's in it
return NO;
}];
JLRoutes支持设置带有可选参数的路由。在路由注册时刻,JLRoute将为带有可选参数和不带可选参数的路由的所有组合注册多个路由。例如,对于路由/the(/foo/:a)(/bar/:b)
,它将注册以下路由
/the/foo/:a/bar/:b
/the/foo/:a
/the/bar/:b
/the
有多种方法可以用于程序性地查询路由(例如,用于提供调试UI)。有一个方法可以获取所有方案的全套路由,另一个方法可以获取特定方案的路由列表。注意,由于它进行了前向声明,您必须导入JLRouteDefinition.h
。
/// All registered routes, keyed by scheme
+ (NSDictionary <NSString *, NSArray <JLRRouteDefinition *> *> *)allRoutes;
/// Return all registered routes in the receiving scheme namespace.
- (NSArray <JLRRouteDefinition *> *)routes;
通过子类化JLRouteDefinition
并使用addRoute:
方法添加您的自定义子类实例,可以控制如何解析路由。
BSD 3条款。有关详细信息,请参阅LICENSE文件。