All Projects → hubrioAU → Xrouter

hubrioAU / Xrouter

Licence: mit
Navigate anywhere in just one line.

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Xrouter

Serving
Kubernetes-based, scale-to-zero, request-driven compute
Stars: ✭ 4,238 (+931.14%)
Mutual labels:  app
Pppc Utility
Privacy Preferences Policy Control (PPPC) Utility
Stars: ✭ 390 (-5.11%)
Mutual labels:  app
Flutter kaiyan
[DEPRECATED] 使用Google跨平台框架Flutter仿写一个开眼视频(Eyepetizer )
Stars: ✭ 404 (-1.7%)
Mutual labels:  app
Cartool
Mac上解压Assets.car文件的小工具(支持右键解压)
Stars: ✭ 375 (-8.76%)
Mutual labels:  app
Flutter Movie
😎 🎬 A Flutter movie app build with Fish-Redux and The Movie DB api.
Stars: ✭ 386 (-6.08%)
Mutual labels:  app
Githubupdates
Cocoa framework to install application updates from GitHub releases.
Stars: ✭ 393 (-4.38%)
Mutual labels:  app
Lcg
吾爱破解第三方安卓应用
Stars: ✭ 371 (-9.73%)
Mutual labels:  app
Sandbox
Development sandbox for front end projects and tutorials.
Stars: ✭ 408 (-0.73%)
Mutual labels:  app
Fluttergrocery Shoppingappui
🍔😋 Grocery Shopping App template UI kit in Flutter
Stars: ✭ 388 (-5.6%)
Mutual labels:  app
Ugank
🍖「有干货」Gank.io 第三方客户端(MVP)
Stars: ✭ 402 (-2.19%)
Mutual labels:  app
Httper Ios
App for developers to test REST API.
Stars: ✭ 376 (-8.52%)
Mutual labels:  rxswift
Spectro
🎶 Real-time audio spectrogram generator for the web
Stars: ✭ 383 (-6.81%)
Mutual labels:  app
Awesome Rxswift
An "awesome" type curated list of RxSwift library and learning material
Stars: ✭ 396 (-3.65%)
Mutual labels:  rxswift
Reactant
Reactant is a reactive architecture for iOS
Stars: ✭ 374 (-9%)
Mutual labels:  rxswift
Lawnchair
No clever tagline needed.
Stars: ✭ 4,720 (+1048.42%)
Mutual labels:  app
Nineanimator
An elegant way of discovering anime on iOS.
Stars: ✭ 369 (-10.22%)
Mutual labels:  app
Rxviewmodel
ReactiveViewModel-esque using RxSwift
Stars: ✭ 392 (-4.62%)
Mutual labels:  rxswift
Wanandroid
🏄 基于Architecture Components dependencies (Lifecycles,LiveData,ViewModel,Room)构建的WanAndroid开源项目。 你值得拥有的MVVM快速开发框架:https://github.com/jenly1314/MVVMFrame
Stars: ✭ 410 (-0.24%)
Mutual labels:  app
Pretzel
Pretzel is Mac desktop app that shows and find keyboard shortcuts based on your current app.
Stars: ✭ 405 (-1.46%)
Mutual labels:  app
Framework7 Template Vue Webpack
Deprecated! Framework7 Vue Webpack starter app template with hot-reload & css extraction
Stars: ✭ 399 (-2.92%)
Mutual labels:  app

XRouter

Build Status CodeCov Badge Codacy Badge
Docs Badge Version License Language

XRouter

Decouple your code with abstract routes, add powerful deep-linking and ditch the boilerplate.

Get Started

Define App Routes

Create an AppRoute+Config.swift file with your abstract routes in it.

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

Create a Router

Extend a concrete Router instance to resolve your view controllers.

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 let .profile(userID):
            guard let profile = profilesRepository.fetch(userId) else {
                throw NotFoundError("Could not find profile with that ID.")
            }

            return UserProfileViewController().configured(with: profile)
        }
    }

}

Use

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

Advanced Usage

RxSwift

XRouter also supports the RxSwift framework out of the box. Bindings exist for navigate(to:), which returns a Completable, and openURL(_:), which returns a Single<Bool>.

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

Deep Link Support

XRouter provides support for deep links and universal links.

You only need to do one thing to add URL support for your routes. Implement the static method 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)
            }
        }
    }

}

Then you can call the openURL(_:animated:completion:) and/or continue(_ userActivity:) methods, e.g. from in your 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)
    }

}

You can even define more advanced URL routing. For example, these rules could be used to match:

  • 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 }
            }
        ])
    }

}

Handling errors

If you handle all navigation errors in the same way, you can override the received(unhandledError:) method.

class Router: XRouter<Route> {

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

}

Or you can set a custom completion handler for some individual navigation action:

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!")
    }
}

Custom Transitions

Here is an example using the popular Hero Transitions library.

Define your custom 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)
      }
  }

And set the transition to your custom transition in your Router:

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

        return .automatic
    }

Documentation

Complete documentation is available here and is generated using Jazzy.

Example

To run the example project, clone the repo, and run it in Xcode 10.

Requirements

Installation

Swift Package Manager

XRouter is available through Swift Package Manager from version 2.0.1 onwards.

CocoaPods

XRouter is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'XRouter'

Author

Reece Como, [email protected]

License

XRouter is available under the MIT license. See the LICENSE file for more info.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].