JLRoutes 2.1

JLRoutes 2.1

测试已测试
语言语言 Obj-CObjective C
许可证 BSD 3.0
发布日期最新发布2017年12月

Joel Levin 维护。



  • 作者:
  • Joel Levin

是什么?

JLRoutes 是一个基于简单块操作的 URL 路由库。它旨在通过最少的代码,使处理应用中的复杂 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文件。