Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ios-utils/XRouter
Navigate anywhere in just one line.
https://github.com/ios-utils/XRouter
app ios routes rxswift swift xrouter
Last synced: 3 months ago
JSON representation
Navigate anywhere in just one line.
- Host: GitHub
- URL: https://github.com/ios-utils/XRouter
- Owner: ios-utils
- License: mit
- Archived: true
- Created: 2019-01-05T15:33:00.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2021-06-03T09:55:31.000Z (over 3 years ago)
- Last Synced: 2024-07-19T22:12:13.058Z (4 months ago)
- Topics: app, ios, routes, rxswift, swift, xrouter
- Language: Swift
- Homepage: https://hubrioau.github.io/XRouter
- Size: 1.64 MB
- Stars: 409
- Watchers: 44
- Forks: 22
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# XRouter
Add powerful deep-linking, simplify navigation and ditch the expensive boilerplate.
## Docs
Complete [documentation is available here](https://hubrioau.github.io/XRouter/) and is generated using [Jazzy](https://github.com/realm/jazzy).
## Get started
### Installation
#### Swift Package Manager (SPM)
XRouter is available via Swift Package Manager version `2.0.1` onwards.
#### CocoaPods
XRouter is available through [CocoaPods](https://cocoapods.org). To install
it, simply add the following line to your Podfile:```ruby
pod 'XRouter'
```### Basic Usage
#### Defining your routes
Create a file containing the routes for your application.```swift
enum Route: RouteType {
case login
case profile(userID: Int)
}
```##### Create a Router
Configure a concrete instance of `XRouter` to resolve a standalone view controller, or start a modal flow by passing a navigation controller.```swift
class Router: XRouter {
override func prepareDestination(for route: Route) throws -> UIViewController {
switch route {
case .login:
return AuthLoginFlowCoordinator().navigationControllercase .profile(let userID):
return UserProfileViewController(profile: try repo.fetch(user: userID))
}
}
}
```##### Perform navigation
```swift
router.navigate(to: .profile(userID: 3355))
```### Advanced Usage
#### 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`:
```swift
enum Route: RouteType {
static func registerURLs() -> URLMatcherGroup? {
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:
```swift
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````swift
enum Route: RouteType {
static func registerURLs() -> URLMatcherGroup? {
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 }
}
])
}
}
```#### Global error navigation handling
If you handle all navigation errors in the same way, you can override the `received(unhandledError:)` method.
```swift
class Router: XRouter {
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:
```swift
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](https://github.com/HeroTransitions/Hero) library.Define your custom transitions:
```swift
/// Perform a cross-fade transition using Hero library.
static let heroCrossFade = RouteTransition { (source, destination, animated, completion) in
source.hero.isEnabled = true
destination.hero.isEnabled = true
destination.hero.modalAnimationType = .fade/* Present the hero animation */
source.present(destination, animated: animated) {
completion(nil)
}
}
```And set the transition to your custom transition in your Router:
```swift
override func transition(for route: Route) -> RouteTransition {
if case .profile = route {
return .heroCrossFade
}return .automatic
}
```#### RxSwift Support
XRouter also supports Rx out of the box. Bindings exist for `navigate(to:)`, which returns a `Completable`, and `openURL(_:)`, which returns a `Single`.
```swift
router.rx.navigate(to: .loginFlow) // -> Completable
router.rx.openURL(url) // -> Single
```## Demo Project
To run the example project, clone the repo, and run it in the latest version of [Xcode](https://developer.apple.com/xcode/).
## License
XRouter is available under the MIT license. See the LICENSE file for more info.