XRouter 2.0.0

XRouter 2.0.0

Reece ComoReece Como 维护。



XRouter 2.0.0

  • 作者:
  • Reece Como

XRouter

只需一行代码即可导航到任何地方。

Codacy Badge CodeCov Badge Build Status Docs Badge Version License Language

XRouter

基本用法

配置

定义路由

enum AppRoute: RouteType {
    case newsfeed
    case login
    case signup
    case profile(userID: Int)
}

创建路由器

class Router: XRouter<AppRoute> {

    override func prepareDestination(for route: AppRoute) throws -> UIViewController {
        switch route {
        case .newsfeed: return newsfeedController.rootViewController
        case .login: return LoginFlowCoordinator().start()
        case .signup: return SignupFlowCoordinator().start()
        case .profile(let userID): return UserProfileViewController(withID: userID)
        }
    }
    
}

使用路由器

// Navigate directly to a route
router.navigate(to: .profile(3355))

// Open a URL
router.openURL(url)

高级用法

RxSwift

XRouter 默认支持 RxSwift 框架。存在用于 navigate(to:) 返回 Completable 的绑定,以及用于 openURL(_:) 返回 Single<Bool> 的绑定。

router.rx.navigate(to: .loginFlow) // -> Completable
router.rx.openURL(url) // -> Single<Bool>

深度链接支持

XRouter 提供了对深度链接和通用链接的支持。

您只需执行一项操作即可为您的路由添加 URL 支持。实现静态方法 registerURLs

enum AppRoute: RouteType {

    static func registerURLs() -> URLMatcherGroup<Route>? {
        return .group {
            $0.map("/products") { .allProducts }
            $0.map("/user/*/logout") { .logout }
            $0.map("/products/{cat}/view") { try .products(category: $0.path("cat")) }
            
            $0.map("/user/{id}/profile") {
                try .viewProfile(withID: $0.path("id"), parameters: $0.query)
            }
        }
    }

}

然后您可以调用 openURL(_:animated:completion:) 和/或 continue(_ userActivity:) 方法,例如从您的 AppDelegate 中调用

extension AppDelegate {

    /// Handle deep links.
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
        return router.openURL(url, animated: false)
    }

    /// Handle universal links.
    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        return router.continue(userActivity)
    }

}

您甚至可以定义更高级的 URL 路由。例如,这些规则可以用来匹配

  • http://example.com/login --> .login
  • https://example.com/signup --> .signup
  • customScheme://myApp/qr-code?code=abcdef... --> .openQRCode("abcdef...")
  • https://www.example.com/products --> .allProducts
  • https://api.example.com/user/my-user-name/logout --> .logout
enum AppRoute: RouteType {

    static func registerURLs() -> URLMatcherGroup<AppRoute>? {
        return .init(matchers: [
            .host("example.com") {
                $0.map("/login") { .login }
                $0.map("/signup") { .signup }
            },
            .scheme("customScheme") {
                $0.map("/qr-code") { .openQRCode($0.query("code")) }
            },
            .group {
                $0.map("/products") { .allProducts }
                $0.map("/user/*/logout") { .logout }
            }
        ])
    }

}

错误处理

如果您以相同的方式处理所有的导航错误,您可以选择覆盖 received(unhandledError:) 方法。

class Router: XRouter<Route> {

    override func received(unhandledError error: Error) {
        log.error("Oh no! An error occured: \(error)")
    }

}

或者您可以为某些单独的导航操作设置自定义的完成处理程序

router.navigate(to: .profilePage(withID: 24)) { (optionalError) in
    if let error = optionalError {
        print("Oh no, we couldn't go here because there was an error!")
    }
}

自定义转场

这里使用流行的Hero Transitions库演示了一个例子。

定义你的自定义过渡动画

  /// Hero cross fade transition
  let heroCrossFade = RouteTransition { (source, dest, animated, completion) in
      source.hero.isEnabled = true
      dest.hero.isEnabled = true
      dest.hero.modalAnimationType = .fade

      // Present the hero animation
      source.present(dest, animated: animated) {
          completion(nil)
      }
  }

并在你的Router中将过渡设置为你的自定义过渡

    override func transition(for route: AppRoute) -> RouteTransition {
        if case Route.profile = route {
          return heroCrossFade
        }

        return .automatic
    }

文档

完整的文档在这里可用,并使用Jazzy生成。

例子

要运行示例项目,请克隆仓库,然后在Xcode 10中运行。

要求

安装

CocoaPods

您可以通过CocoaPods获取XRouter。要安装它,请在Podfile中添加以下行

pod 'XRouter'

作者

Reece Como, [email protected]

许可证

XRouter可在MIT许可证下使用。更多信息请参阅LICENSE文件。