Scotty

CI Status Version Carthage compatible License Platform codecov

目的

该库提供了一个简单的抽象层,用于访问 iOS 应用程序的各种入口点。 URL、应用程序快捷方式项目、用户活动、通知响应,甚至自定义类型都可以转换为 Route(路由)。 这些路由代表了你的应用可以深度链接到的各种目的地,使你可以拥有一个单一的代码路径来执行所有应用程序链接。

核心概念

用法

应该创建 RouteController(路由控制器)的一个实例,并将其保存在你的 Application Delegate(应用程序委托)可以访问的地方,以便将相关的回调转发给它。 虽然 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/UIApplicationShortcutItemRouteController 兼容,需要对其进行扩展以提供 Route 对象。 一个简单的实现可能如下所示:

extension URL {

    public var route: Route<UITabBarController>? {
        let components = URLComponents(url: self, resolvingAgainstBaseURL: false)!
        return Route.route(forIdentifier: components.path)
    }
}

在处理 URL 时,除了提供 Route 对象外,你还需要使用自己的 URL scheme(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 指示一个执行的适当时间。

示例

要运行示例项目,请克隆 repo,并首先从 Example 目录运行 pod install

要求

安装

Swift Package Manager

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 中所述的步骤进行操作。

贡献

请参阅 CONTRIBUTING 文档。 谢谢,贡献者!