Router

⚠️已弃用,不再支持。 使用风险自负。
该方案曾被广泛使用,但在权衡利弊之后,我们现在更倾向于使用原生 Flow Controllers 或 Coordinators,详情请参考这里
应该始终首选原生方案 (此处为双关语),并且我们认为减少依赖项是我们应该始终努力的目标。

Router (路由)

Language: Swift Platform: iOS 8+ Carthage compatible Build Status License: MIT Release version

原因 - 开始使用 - 安装

Router

原因

因为传统的 App 导航会在 ViewControllers 之间引入紧耦合。 复杂的 App 导航看起来就像一个巨大的蜘蛛网

除了 导航责任被分散到各个 ViewControllers 之外,修改一个 ViewController 可能会导致级联重新编译,从而导致编译速度变慢

方法

通过使用 Navigation enum 进行导航,我们可以解耦 ViewControllers 之间的关系。 也就是说,它们不再互相了解。 因此,修改 VCA 不会再触发 VCB 重新编译 \o/

// navigationController?.pushViewController(AboutViewController(), animated: true)
navigate(.about)

导航代码现在被封装在一个 AppNavigation 对象中。

优点

开始使用

1 - 声明您的 Navigation 枚举

enum MyNavigation: Navigation {
    case about
    case profile(Person)
}

Swift 枚举可以接受参数! 这对我们来说非常棒,因为这就是我们将在 ViewControllers 之间传递数据的方式 :)

2 - 声明您的 App Navigation

struct MyAppNavigation: AppNavigation {

    func viewcontrollerForNavigation(navigation: Navigation) -> UIViewController {
        if let navigation = navigation as? MyNavigation {
            switch navigation {
            case .about:
                return AboutViewController()
            case .profile(let p):
                return ProfileViewController(person: p)
            }
        }
        return UIViewController()
    }

    func navigate(_ navigation: Navigation, from: UIViewController, to: UIViewController) {
      from.navigationController?.pushViewController(to, animated: true)
    }
}

一个很棒的事情是,如果某个导航案例没有被处理,swift 编译器会报错! 如果使用字符串 URLs,则不会出现这种情况 ;)

3 - 在 App 启动时注册您的导航

AppDelegate.swift 中,在所有事情之前

Router.default.setupAppNavigation(appNavigation: MyAppNavigation())

4 - 替换您的 View Controllers 中的导航

您现在可以从您的 View Controllers 中调用导航

navigate(MyNavigation.about)

使用您自己的枚举类型 (这里是 MyNavigation) 来桥接 Navigation,这样我们就不必输入我们自己的类型了。

extension UIViewController {

    func navigate(_ navigation: MyNavigation) {
        navigate(navigation as Navigation)
    }
}

您现在可以这样写

navigate(.about)

Bonus - 跟踪

解耦导航的另一个好处是,您现在也可以从 View Controllers 中提取跟踪代码。 只要发生导航,您就可以收到路由器的通知。

Router.default.didNavigate { navigation in
    // Plug Analytics for instance
    GoogleAnalitcs.trackPage(navigation)
}

减少编译时间

Swift 3 编译器中存在一个严重的错误,即使文件没有更改,编译器也会重新构建文件。 这在以下位置有记录:https://forums.developer.apple.com/thread/62737?tstart=0

由于此错误,编译可能会这样进行

更改 ViewController1 -> Build
-> 编译 ViewController1,它在 MyAppNavigation 中被引用,所以
MyAppNavigation 会被重新编译。 MyAppNavigationAppDelegate 中被引用,这会重新编译,它又引用了 ... App -> ViewController2 -> ViewController3 -> ViewControllerX,您明白了吧。 在您意识到之前,整个 App 都会被重建 :/

一个好消息是,大多数的 App 耦合通常来自导航。 而 Router 可以解耦导航。

我们可以阻止这种无稽之谈,直到 Xcode 的未来版本修复此问题。 Router 可以通过在运行时注入我们的 AppNavigation 实现来帮助我们管理此问题。

在您的 AppDelegate.swift

// Inject  your AppNavigation  at runtime to avoid recompilation of AppDelegate :)
Router.default.setupAppNavigation(appNavigation: appNavigationFromString("YourAppName.MyAppNavigation"))

并确保您的 AppNavigation 实现现在是一个 class,并且是 RuntimeInjectable (运行时可注入的)

class MyAppNavigation: RuntimeInjectable, AppNavigation {

安装

Carthage

github "freshOS/Router"

手动

只需将 Router.swift 文件复制并粘贴到您的 Xcode 项目中 :)

作为框架

获取此存储库并在示例项目中构建 Framework 目标。 然后链接到该框架。

支持者

喜欢这个项目吗? 请喝咖啡或每月捐款支持我们,并帮助我们继续我们的活动 :)

赞助商

成为赞助商,并将您的徽标放在我们在 Github 上的 README 中,并链接到您的网站 :)