📱📲 Navigate between view controllers with ease. 💫 🔜 More stable version (written in Swift 5) coming soon.

Overview

CoreNavigation 📱 📲

Navigate between view controllers with ease. 💫

🔜 More stable version (written in Swift 5) coming soon.

Platform Build Status Documentation codecov CocoaPods Compatible Carthage compatible

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 '
   
    '
    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

Navigate.present { $0
    .to(PersonProfileViewController())
    .withData(person)
}

Pushing view controller:

Code Example

Navigate.push { $0
    .to(PersonProfileViewController())
    .withData(person)
}

Routing & deep linking:

Why use the Destination instead navigating directly to view controller?

Read about it on Medium:

Defining Destination

Code Example

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

// 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

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

Example Apps

Running the Tests

Available in CoreNavigationTests target.

Versioning

Current release:

  • 1.0.0-beta-4

Authors

Contributing

Please read Contributing 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 file for details.

You might also like...
🎯Linker  Lightweight way to handle internal and external deeplinks in Swift for iOS
🎯Linker Lightweight way to handle internal and external deeplinks in Swift for iOS

Linker Lightweight way to handle internal and external deeplinks in Swift for iOS. Installation Dependency Managers CocoaPods CocoaPods is a dependenc

Interface-oriented router for discovering modules, and injecting dependencies with protocol in Objective-C and Swift.
Interface-oriented router for discovering modules, and injecting dependencies with protocol in Objective-C and Swift.

ZIKRouter An interface-oriented router for managing modules and injecting dependencies with protocol. The view router can perform all navigation types

A library for managing complex workflows in Swift
A library for managing complex workflows in Swift

Welcome SwiftCurrent is a library that lets you easily manage journeys through your Swift application. It comes with built-in support for UIKit and Sw

 ZPPRouter 组件化路由 swift
ZPPRouter 组件化路由 swift

ZPPRouter 面向组件协议 组件获取实例为协议类型 注: SPM 每一个组件最终生成的都是 framwork库 意味着组件存在命名空间(优点) Example To run the example project, clone the repo, and run pod install fro

A deep copy of Pinterest in Swift
A deep copy of Pinterest in Swift

Demo YouTube: Demo (2 minutes) 优酷:http://v.youku.com/v_show/id_XMzE3OTc5NDY2MA==.html?spm=a2h3j.8428770.3416059.1 The app is actually smoother than sh

RoutingKit - Routing library With Swift

RoutingKit Usage struct MessageBody: Body { typealias Response = String

A simple, powerful and elegant implementation of the coordinator template in Swift for UIKit
A simple, powerful and elegant implementation of the coordinator template in Swift for UIKit

A simple, powerful and elegant implementation of the coordinator template in Swift for UIKit Installation Swift Package Manager https://github.com/bar

A macOS Monterey Patcher that will be coming soon.
A macOS Monterey Patcher that will be coming soon.

A macOS Monterey UI patcher. It uses my MontereyPatcher-CLI patcher as its base, and it will hopefully build upon that. Resources: MontereyPatcher-CLI

Flip is a book tracking app built for iOS and iPadOS. Coming soon to watchOS and macOS.
Flip is a book tracking app built for iOS and iPadOS. Coming soon to watchOS and macOS.

Flip Flip is a project aimed at helping users manage their library of books. It has a clean user interface, allows users to sort and filter their libr

LNPopupController is a framework for presenting view controllers as popups of other view controllers, much like the Apple Music and Podcasts apps.
LNPopupController is a framework for presenting view controllers as popups of other view controllers, much like the Apple Music and Podcasts apps.

LNPopupController LNPopupController is a framework for presenting view controllers as popups of other view controllers, much like the Apple Music and

⛵️ URLNavigator provides an elegant way to navigate through view controllers by URLs.

URLNavigator ⛵️ URLNavigator provides an elegant way to navigate through view controllers by URLs. URL patterns can be mapped by using URLNavigator.re

SwipeViewController is a Swift modification of RKSwipeBetweenViewControllers - navigate between pages / ViewControllers
SwipeViewController is a Swift modification of RKSwipeBetweenViewControllers - navigate between pages / ViewControllers

SwipeViewController What is SwipeViewController? SwipeViewController enables you to modify the navigation bar and implement 'Swipe Buttons' that can u

Custom-Transition - A repo about custom transition between two view controllers

Custom-Transition in SWIFT This is a repo about custom transition between two vi

🏄‍♂️ UITextField-Navigation makes it easier to navigate between UITextFields and UITextViews
🏄‍♂️ UITextField-Navigation makes it easier to navigate between UITextFields and UITextViews

' __________________ _______ _________ _______ _________ _______ _ ______ ' |\ /|\__ __/\__ __/( ____ \|\ /

SwiftWebKit - This app look like a browser, but you can navigate between 2 sites
SwiftWebKit - This app look like a browser, but you can navigate between 2 sites

import UIKit import WebKit My first app for WebKit. This app look like a browser

A stable, mature and comprehensive Objective-C library for Twitter REST API 1.1
A stable, mature and comprehensive Objective-C library for Twitter REST API 1.1

STTwitter A stable, mature and comprehensive Objective-C library for Twitter REST API 1.1 Like a FOSS version of Twitter Fabric TwitterKit, without th

Stable Diffusion inference on iOS / macOS using MPSGraph
Stable Diffusion inference on iOS / macOS using MPSGraph

🍁 Maple Diffusion Maple Diffusion runs Stable Diffusion models locally on macOS / iOS devices, in Swift, using the MPSGraph framework (not Python). M

SPLarkController - Custom transition between controllers. Settings controller for your iOS app.
SPLarkController - Custom transition between controllers. Settings controller for your iOS app.

SPLarkController About Transition between controllers to top. You can change animatable height after presentation controller. For presentation and dis

Custom transition between controllers. Settings controller for your iOS app.
Custom transition between controllers. Settings controller for your iOS app.

SPLarkController About Transition between controllers to top. You can change animatable height after presentation controller. For presentation and dis

Releases(0.4.0)
Owner
Aron Balog
Lotus Lambda evangelist
Aron Balog
Eugene Kazaev 713 Dec 25, 2022
Appz 📱 Launch external apps, and deeplink, with ease using Swift!

Appz ?? Deeplinking to external applications made easy Highlights Web Fallback Support: In case the app can't open the external application, it will f

Kitz 1.1k May 5, 2021
Provides a custom presentation modifier that provides more options including full screen presentations. (iOS)

Presentation Also available as a part of my SwiftUI+ Collection – just add it to Xcode 13+ Provides a custom presentation modifier that provides more

SwiftUI+ 15 Dec 3, 2022
A bidirectional Vapor router with more type safety and less fuss.

vapor-routing A routing library for Vapor with a focus on type safety, composition, and URL generation. Motivation Getting started Documentation Licen

Point-Free 68 Jan 7, 2023
A bidirectional router with more type safety and less fuss.

swift-url-routing A bidirectional URL router with more type safety and less fuss. This library is built with Parsing. Motivation Getting started Docum

Point-Free 242 Jan 4, 2023
LiteRoute is easy transition for your app. Written on Swift 4

LiteRoute Description LiteRoute is easy transition between VIPER modules, who implemented on pure Swift. We can transition between your modules very e

Vladislav Prusakov 90 Mar 12, 2021
Monarch Router is a Declarative URL- and state-based router written in Swift.

Monarch Router is a declarative routing handler that is capable of managing complex View Controllers hierarchy transitions automatically, decoupling View Controllers from each other via Coordinator and Presenters. It fits right in with Redux style state flow and reactive frameworks.

Eliah Snakin 31 May 19, 2021
SwiftRouter - A URL Router for iOS, written in Swift

SwiftRouter A URL Router for iOS, written in Swift, inspired by HHRouter and JLRoutes. Installation SwiftRouter Version Swift Version Note Before 1.0.

Chester Liu 259 Apr 16, 2021
🍞 [Beta] A view controller that can unwind like presentation and navigation.

FluidPresentation - no more handling presented or pushed in view controller A view controller that supports the interactive dismissal by edge pan gest

Muukii 19 Dec 22, 2021
A demonstration to the approach of leaving view transition management to a router.

SwiftUI-RouterDemo This is a simplified demonstration to the approach of leaving view transition management to a router.

Elvis Shi 3 May 26, 2021