CoreNavigation alternatives and similar libraries
Based on the "App Routing" category.
Alternatively, view CoreNavigation alternatives based on common mentions on social networks and blogs.
-
RxFlow
RxFlow is a navigation framework for iOS applications based on a Reactive Flow Coordinator pattern -
RouteComposer
Protocol oriented, Cocoa UI abstractions based library that helps to handle view controllers composition, navigation and deep linking tasks in the iOS application. Can be used as the universal replacement for the Coordinator pattern. -
ZIKRouter
Interface-oriented router for discovering modules, and injecting dependencies with protocol in Objective-C and Swift. -
Composable Navigator
An open source library for building deep-linkable SwiftUI applications with composition, testing and ergonomics in mind -
DZURLRoute
DZURLRoute是支持基于标准URL进行Native页面间跳转的Objective-C实现。方便您架构页面之间高内聚低耦合的开发模式。他的核心思想是把每一个页面当成一个资源,通过标准的URL协议(统一资源定位符)来定位到每一个可触达的页面(资源)。 -
Weavy
DISCONTINUED. Reactive navigation framework based on a weaving pattern (fits well with RxSwift)
CodeRabbit: AI Code Reviews for Developers
Do you think we are missing an alternative of CoreNavigation or a related project?
README
CoreNavigation 📱📲
Navigate between view controllers with ease. 💫
🔜 More stable version (written in Swift 5) coming soon.
[Documentation](docs/badge.svg)
- Getting Started
- API Reference
- Example Use
- Defining view controller
- Presenting view controller
- Pushing view controller
- Routing & deep linking
- Configuration
- [Animating]
- [Observing completion]
- [Observing success]
- [Observing failure]
- [Embedding]
- [Passing data]
- [Caching]
- [Protection]
- [State restoration]
- [Specifying origin view controller]
- Example Apps
- [BiometricAuthExample]
- [PassingDataExample]
- [DeepLinkingExample]
- Running the Tests
- Versioning
- Authors
- License
Getting Started
These instructions will help you integrate CoreNavigation into your project.
Prerequisities
- Xcode 9 or higher
- iOS 8 or higher
- Cocoapods
Installation
CocoaPods
CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:
$ gem install cocoapods
CocoaPods 1.1+ is required to build CoreNavigation 1.0+.
To integrate CoreNavigation into your Xcode project using CocoaPods, specify it in your Podfile:
target '<Your Target Name>' do
use_frameworks!
pod 'CoreNavigation', '1.0.0-beta-4'
end
Then, run the following command:
$ pod install
Carthage
Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate CoreNavigation into your Xcode project using Carthage, specify it in your Cartfile:
github "aronbalog/CoreNavigation" == "1.0.0-beta-4"
API Reference
API reference
Example Use
Defining view controller:
class PersonProfileViewController: UIViewController, DataReceivable {
// DataReceivable associatedtype
typealias DataType = Person
func didReceiveData(_ data: Person) {
// configure UI with data
}
}
Presenting view controller:
[Code Example](Playgrounds/Presenting.playground/Contents.swift)
Navigate.present { $0
.to(PersonProfileViewController())
.withData(person)
}
Pushing view controller:
[Code Example](Playgrounds/Pushing.playground/Contents.swift)
Navigate.push { $0
.to(PersonProfileViewController())
.withData(person)
}
Routing & deep linking:
- [DeepLinkingExample App][DeepLinkingExample]
Why use the Destination
instead navigating directly to view controller?
Read about it on Medium:
- #0 present & push… For how long?
- #1 Forget about segues.
- #2 Passing data between view controllers.
- #3 Handle Universal Links Like a Boss.
Defining Destination
[Code Example](Playgrounds/Routing.playground/Contents.swift)
struct PersonProfile: Destination, Routable {
// Destination associatedtype
typealias ViewControllerType = PersonProfileViewController
// Routable patterns
static var patterns: [String] = [
"https://myapp.com/person/:personId(.*)",
"https://myapp.com/user/:personId(.*)"
]
let personId: String
init(_ personId: String) {
self.personId = personId
}
var parameters: [String : Any]? {
return [
"personId": personId
]
}
static func resolve(context: Context<PersonProfile>) {
guard let personId = context.parameters?["personId"] as? String else {
// cancel navigation with some error
context.cancel(error: NavigationError.Destination.notFound)
return
}
// fetch person
fetchPerson(id: personId, completion: { (person: Person) in
// continue to navigation
context.complete(data: person)
}, failure: { (error: Error) in
// cancel navigation with some error
context.cancel(error: error)
})
}
}
Registering Routable
types
In order to use Matchable
types (String
, URL
, etc.) to navigate, every Destination
type must be registered. Think about it as internal DNS.
PersonProfile.register()
Additional syntax
Navigate.router.register(routableType: PersonProfile.self)
Destination
type can be routable without conforming to Routable
protocol. Use this if you intend to create some kind of destination manifest and/or if route patterns are fetched from an external source:
Navigate.router.register(destinationType: PersonProfile.self, patterns: [
"https://myapp.com/person/:personId(.*)",
"https://myapp.com/user/:personId(.*)"
])
Additional syntax
PersonProfile.self <- [
"https://myapp.com/person/:personId(.*)",
"https://myapp.com/user/:personId(.*)"
]
Settings.self <- [
"https://myapp.com/settings"
]
Navigating using Destination
// present
Navigate.present { $0
.to(PersonProfile("sherlock_holmes"))
...
}
// or push
Navigate.push { $0
.to(PersonProfile("sherlock_holmes"))
...
}
Additional syntax
// present
PersonProfile("sherlock_holmes").present { $0
...
}
// or push
PersonProfile("sherlock_holmes").push { $0
...
}
Additional syntax
// present
PersonProfile("sherlock_holmes").present()
// or push
PersonProfile("sherlock_holmes").push()
Navigating using route
[Code Example](Playgrounds/Routing.playground/Contents.swift)
// present
Navigate.present { $0
.to("https://myapp.com/person/sherlock_holmes")
...
}
// or push
Navigate.push { $0
.to("https://myapp.com/person/sherlock_holmes")
...
}
Additional syntax
// present
"https://myapp.com/person/sherlock_holmes".present { $0
...
}
// or push
"https://myapp.com/person/sherlock_holmes".push { $0
...
}
Additional syntax
// present
"https://myapp.com/person/sherlock_holmes".present()
// or push
"https://myapp.com/person/sherlock_holmes".push()
Getting view controller asynchronously using Destination
PersonProfile("sherlock_holmes").viewController { (viewController) in
// vc is `PersonProfileViewController`
}
Getting view controller asynchronously using route
"https://myapp.com/person/sherlock_holmes".viewController { (viewController) in
...
}
Getting view controller synchronously using Destination
[Code Example](Playgrounds/Routing.playground/Contents.swift)
do {
let viewController = try PersonProfile("sherlock_holmes").viewController()
} catch let error {
// handle error
}
Getting view controller synchronously using route
do {
let viewController = try "https://myapp.com/person/sherlock_holmes".viewController()
} catch let error {
// handle error
}
Note:
If you implement custom destination resolving, **it must happen on the main thread; otherwise, an error is thrown.
Matchable protocol
URL
types can also be used to navigate or resolve view controller. Actually, any type conforming Matchable
protocol can be used.
Conforming to matchable:
struct Person {
let id: String
...
}
extension Person: Matchable {
var uri: String {
return "https://myapp.com/person/" + id
}
}
Example usage:
let person: Person = Person(id: "sherlock_holmes", ...)
// getting view controller
let personProfileViewController = try! person.viewController
// or navigating
person.present()
person.push()
// or more configurable syntax
Navigate.present { $0
.to(person)
...
}
Configuration
- [Animating]
- [Observing completion]
- [Observing success]
- [Observing failure]
- [Embedding]
- [Passing data]
- [Caching]
- [Protection]
- [State restoration]
- [Specifying origin view controller]
Example Apps
- [BiometricAuthExample]
- [PassingDataExample]
- [DeepLinkingExample]
Running the Tests
Available in CoreNavigationTests
target.
Versioning
Current release:
- 1.0.0-beta-4
Authors
Contributing
Please read [Contributing](CONTRIBUTING.md) for details on code of conduct, and the process for submitting pull requests.
License
This project is licensed under the MIT License - see the [LICENSE](LICENSE.md) file for details.
<!--- example apps -->
*Note that all licence references and agreements mentioned in the CoreNavigation README section above
are relevant to that project's source code only.