- August 12, 2025
- Mins Read
Navigate between view controllers with ease. 💫
🔜 More stable version (written in Swift 5) coming soon.
These instructions will help you integrate CoreNavigation into your project.
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 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”
class PersonProfileViewController: UIViewController, DataReceivable {
// DataReceivable associatedtype
typealias DataType = Person
func didReceiveData(_ data: Person) {
// configure UI with data
}
}
Navigate.present { $0
.to(PersonProfileViewController())
.withData(person)
}
Navigate.push { $0
.to(PersonProfileViewController())
.withData(person)
}
Why use the Destination
 instead navigating directly to view controller?
Read about it on Medium:
Destination
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)
})
}
}
Routable
 typesIn 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”
]
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()
// 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()
Destination
PersonProfile(“sherlock_holmes”).viewController { (viewController) in
// vc is `PersonProfileViewController`
}
“https://myapp.com/person/sherlock_holmes”.viewController { (viewController) in
…
}
Destination
do {
let viewController = try PersonProfile(“sherlock_holmes”).viewController()
} catch let error {
// handle error
}
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.
URL
 types can also be used to navigate or resolve view controller. Actually, any type conforming Matchable
 protocol can be used.
struct Person {
let id: String
…
}
extension Person: Matchable {
var uri: String {
return “https://myapp.com/person/” + id
}
}
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)
…
}
Available in CoreNavigationTests
 target.
Current release:
Recognize your user's voice elegantly without having to figure out authorization and audio engines. SwiftSpeech Examples Features Installation Getting Started ...
Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 14.0 Installation ...
SlidingRuler is a Swift package containing a SwiftUI control that acts like an linear infinite slider or a finite, more precise ...
SkeletonUI aims to bring an elegant, declarative syntax to skeleton loading animations. Get rid of loading screens or spinners and ...