Scotty
目的
这个库提供了一种简化的方式来处理 iOS 应用的各种入口点。例如 URL、应用程序快捷项、用户活动、通知响应,以及自定义类型都可以转换成路由。这些路由表示了您的应用可以深链接到的各种目的地,允许您拥有一个单一的代码路径,通过这个路径来执行所有应用链接。
关键概念
- 路由 - 一种抽象表示,表示从应用的根状态移动到特定最终目的地所需的代码。
- RouteController - 与之创建并使用具有根视图控制器的一种对象,负责执行路由。
- RouteAction - 当任务完成后,路由目的地可以采取的动作。
用法
应该在某个您的应用程序代理可以访问的地方创建并保留 RouteController 的一个实例,以便将相关的回调转发给它。虽然 RouteController 可以被包装并作为单例处理,但这不是必须的。
class AppDelegate: UIResponder, UIApplicationDelegate {
var routeController: RouteController<UITabBarController>?
//In this implementation, our root view controller is a UITabBarController
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]?) -> Bool {
if let window = window, let rootVC = window.rootViewController as? UITabBarController {
routeController = RouteController(root: rootVC)
}
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return routeController?.open(url.route) ?? false
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
return routeController?.open(userActivity) ?? false
}
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
completionHandler(routeController?.open(shortcutItem) ?? false)
}
}
为了使 URL
/NSUserActivity
/UIApplicationShortcutItem
与 RouteController
兼容,它们需要扩展以销售 Route
对象。一个简单的实现可能如下所示
extension URL {
public var route: Route<UITabBarController>? {
let components = URLComponents(url: self, resolvingAgainstBaseURL: false)!
return Route.route(forIdentifier: components.path)
}
}
在处理 URL 时,除了销售 Route
对象之外,您还需要配置您自己的 URL 方案。有关此过程的更多信息,请参阅 Apple。
创建路由
创建一个新的路由就像创建一个新的 Route
实例一样简单。
extension Route where Root == UITabBarController {
static var leftTab: Route {
return Route(identifier: .leftTabRoute) { root, options -> Bool in
root = 0
if let routeRespondableController = root.selectedViewController as? RouteRespondable {
routeRespondableController.setRouteAction {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
print("LeftTab successfully reached!")
}
}
}
return true
}
}
}
上述示例创建了一个静态实例的 Route
结构,旨在导航到示例应用的最左边的标签。标识符用于在将路由销售类型(如 URL
)转换为其他类型时区分此路由。
尾部闭包是路由的机制。给定您的根视图控制器的实例以及提供的任何路由请求选项,此闭包应执行对视图控制器层次结构进行更改所必需的更改,以达到目的地。如果可以成功到达目的地,则此闭包应返回 true。否则,应返回 false。
路由操作
路由操作是在特定路由目的地可以执行的操作闭包。如果路由符合 RouteRespondable 协议,它将有一个公有的 routeAction 属性,可以在路由内部设置。当达到此目的地时,它将向 routeAction 指示一个合适的时间来执行。
示例
要运行示例项目,首先在 Example 目录中克隆存储库,然后运行 pod install
。
要求
- iOS 9.0+
- Swift 5.0
安装
Swift包管理器
dependencies: [
.package(url: "https://github.com/BottleRocketStudios/iOS-Scotty.git", from: "2.1.0")
]
CocoaPods
将以下内容添加到您的Podfile中
pod 'Scotty'
请确保您已选择使用框架
use_frameworks!
然后使用CocoaPods 0.36或更高版本运行pod install
Carthage
将以下内容添加到您的Cartfile中
github "BottleRocketStudios/iOS-Scotty"
运行carthage update
并按照Carthage的README中描述的步骤进行操作。