Corridor
减少自定义 URL 匹配和解析逻辑的编写时间。使用单个字符串定义您支持的任何 URL 格式,并让 Corridor 执行繁重的工作。
假设您想处理一个类似 https://example.com/user/15127128
的用户个人资料 universal-link。
(1) 创建一个 路由 —— 一个包含您想要从 URL 中提取的所有值的 Codable 结构。一旦 URL 匹配,userId 将具有值为 15127128
struct ViewUserProfile: CorridorRoute {
let userId: Int
}
(2) 注册格式: "/user/:userId{int}"
router.register("/user/:userId{int}", { try corridorResponse($0, ViewUserProfile.self) })
现在,使用方法
(3) 使用 url https://example.com/user/15127128
调用 attemptMatch(_:URL)
来获取匹配响应
let result = router.attemptMatch(url)
(4) 在结果上切换到 route
let route = result.route
switch route {
case let route as ViewUserProfile:
print(route.userId)
default:
print("url not matched")
}
15127128
成功了!
概述
查看使用 Corridor 的 示例项目
路由
符合 CorridorRoute
协议的结构。其变量对应于 URL 中包含的值。它在 URL 匹配时创建。
路由
路由加速了URL与路由之间的匹配过程。
let router = CorridorRouter()
让我们注册一种URL类型。
router.register("/user/:userId{int}", { try corridorResponse($0, ViewUserProfile.self) })
ViewUserProfile是我们首次示例中定义的结构体。
"/user/:userId{int}"
是URL格式。它匹配以/user
开头,之后跟有整数的URL。
{ try corridorResponse($0, ViewUserProfile.self) }
是一个当URL匹配时填充ViewUserProfile
路由的闭包。
URL格式
URL格式分为路径和查询两部分。
- 路径:包括由
/
分隔的所有URL值。 - 查询:URL最后
/
之后的键值对。
URL格式必须以一个正斜杠
/
开始。
格式化路径
假设你想匹配以/user/12891
形式出现的URL,这个URL从user
开头并以数字结尾。
这个URL的格式是"/user/:userId{int}"
,其中user
后面的数字被表示为:userId{int}
。
你想提取的每个参数遵循形式:paramName{基础类型}
或:paramName
。
paramName
和路由中的变量名相同基础类型
指示paramName
的类型
所以,在没有明确基础类型的情况下:userId
会映射到路由中的let userId: String
,而:userId{int}
会映射到let userId: Int
。
URL定义必须以一个正斜杠
/
开始
基础类型'string'映射到String
基础类型'int'映射到Int
格式化查询
假设你想匹配以/user?userId=12891
形式出现的URL,该URL从user
路径开始,并在参数中有数字形式的userId
值。
这个URL的格式是"/user/?:userId{int}"
,其中?
之后的内容都是查询部分。
可选参数
假设userId
值是可选的,所以/user&userId=12891
和/user
可以映射到同一个路线。
这个URL的格式是"/user/?:userId{int?}"
字面量
假设我们想要匹配形式为/user&userId=12891&sourceType=email
的URL,其中('sourceType', 'email')对出现在查询中。
这种URL的格式为:"/user/?:userId{int}&&:sourceType{'email'}"
URL格式必须使用'&'符号分隔连续的查询参数。
支持自定义基类型
URL定义"/user/:userId{int}?:nickname{string}"
包含内置基类型:"int"
、"string"
和"bool"
。每个基类型映射到一个Swift类型
"int" -> Int
"string" -> String
"bool" -> Bool
任何基类型都可以用方括号括起来,以表示逗号分隔的值列表。例如:
"[int]" -> [Int]
。
如果你想要使用一个不是内置基类型的基类型,这里有一个例子
(1) 定义一个名为"uint"的基类型,该类型将值转换为UInt
private struct CorridorTypeUInt: CorridorTypeProtocol {
let name = "uint"
func convertToType(from value: String) -> Any? {
return UInt(value)
}
}
基类型名称必须是字母的,且不能与任何现有的内置基类型名称相同
(2) 使用自定义基类型实例化CorridorTypes
let baseTypes = CorridorTypes(customTypes: [CorridorTypeUInt()])
(3) 带有基类型实例化路由器
let router = CorridorRouter(corridorTypes: baseTypes)
现在,使用方法
struct ViewUserProfile: CorridorRoute {
let userId: UInt
let nickname: String?
}
router.register("/user/:userId{uint}?:nickname{string}", { try corridorResponse($0, ViewUserProfile.self) })
(4) 使用URLwww.example.com/8971/?nickname=Bob
调用attemptMatch(_:URL)
let result = router.attemptMatch(url)
let route = routeResponse.route as! ViewUserProfile
print(route.userId)
8971
Voila!
匹配全局查询参数
如果查询参数(如跟踪ID或用户ID)包含在许多URL中,怎么办?
假设你的URL中包含一个查询参数sourceUserId
来跟踪点击URL的用户。
你可以在所有路由中包含let sourceUserId: String?
,这样做既麻烦又容易出错。现在有CorridorGlobalParams来解决问题!
(1) 创建一个遵循CorridorGlobalParams
的struct
struct GlobalParams: CorridorGlobalParams {
let sourceUserId: String?
}
(2) 创建一个映射
let mapping = GlobalQueryOptionalParamsMapping(params: ["sourceUserId"],
decoder: { try corridorGlobalParamsResponse($0, GlobalParams.self) })
(3) 使用映射实例化路由器
let router = CorridorRouter(globalQueryOptionalParamsMapping: mapping)
现在,使用方法
(4) 使用URLwww.example.com/news_feed/?sourceUserId=abc123
调用attemptMatch(_:URL)
let result = router.attemptMatch(url)
let globalParams = routeResponse.globalParams as! GlobalParams
print(globalParams.sourceUserId)
abc123
Voila!
安装
Corridor支持多种方法在项目中安装库。
CocoaPods
要使用CocoaPods将Corridor集成到Xcode项目中,在Podfile
中指定它。
pod 'Corridor','~> 0.0.1'
在您的Podfile
中另外一行也要包含
use_frameworks!
Carthage
要使用 Carthage 将 Corridor 集成到您的 Xcode 项目中,请在您的 Cartfile
中指定它
github "Nextdoor/corridor" ~> 0.0.1'
运行 carthage
构建框架,然后将构建好的 Corridor.framework
拖到您的 Xcode 项目中。
Swift 包管理器
要使用 Swift 包管理器将 Corridor 集成到您的 Xcode 项目中,将它添加到您的 Package.swift
中的 dependencies
值
dependencies: [
.package(url: "https://github.com/Nextdoor/corridor.git", from: "0.0.1")
]
贡献
- 如果您有任何功能请求或发现了一个错误,请打开一个问题
- 如果您想贡献更改,请提交一个拉取请求
许可证
Corridor 在 Apache 2.0 许可证下发布。有关详细信息,请参阅LICENSE