Skip to content

Instantly share code, notes, and snippets.

@gbasile
Last active April 28, 2021 10:15
Show Gist options
  • Save gbasile/0a9d8cda4f3c9c00d13d27e250bb71ce to your computer and use it in GitHub Desktop.
Save gbasile/0a9d8cda4f3c9c00d13d27e250bb71ce to your computer and use it in GitHub Desktop.
A couple of different approaches for Routers on iOS. (by Alexandros, Kamil, Jader & Giuseppe)
struct NavigatorTypeV2 {}
struct Device {}
protocol Router: class {
var navigator: NavigatorTypeV2 { get }
}
extension Router {
public var navigator: NavigatorTypeV2 { fatalError("Not implemented. This router uses a legacy navigator or custom navigation.") }
}
protocol OnboardingRouterHandler: class {
func onDeviceOnboarded(device: Device)
func onOnboardCancelled()
}
class OnboardingPRouter: Router {
private unowned let parentRouter: OnboardingRouterHandler
init(parentRouter: OnboardingRouterHandler) {
self.parentRouter = parentRouter
}
func start() {
// ...
}
func cancel() {
parentRouter.onOnboardCancelled()
}
func onLastStep(with device: Device) {
parentRouter.onDeviceOnboarded(device: device)
}
}
protocol TutorialRouterHandler: class {
func onTutorialCompleted()
func onTutorialCancelled()
}
class TutorialRouter: Router {
private unowned let parentRouter: TutorialRouterHandler
init(parentRouter: TutorialRouterHandler) {
self.parentRouter = parentRouter
}
func start() {
// ...
}
func onLastStep() {
parentRouter.onTutorialCompleted()
}
func onExit() {
parentRouter.onTutorialCancelled()
}
}
class DashboardRouter: Router {
func start() {
let onboardingRouter = OnboardingPRouter(parentRouter: self)
onboardingRouter.start()
}
}
// MARK: Tutorial routing
extension DashboardRouter: TutorialRouterHandler {
func onTutorialCompleted() {
print("User completed tutorial")
}
func onTutorialCancelled() {
print("User Cancelled tutorial")
}
}
// MARK: Onboarding routing
extension DashboardRouter: OnboardingRouterHandler {
func onDeviceOnboarded(device: Device) {
print("The device onboarded is \(device)")
let tutorialRouter = TutorialRouter(parentRouter: self)
tutorialRouter.start()
}
func onOnboardCancelled() {
print("User Cancelled Onboarding")
}
}
struct NavigatorTypeV2 {}
struct Device {}
protocol Router: class {
var navigator: NavigatorTypeV2 { get }
func childDidFinish<T>(result: T)
}
extension Router {
public var navigator: NavigatorTypeV2 { fatalError("Not implemented. This router uses a legacy navigator or custom navigation.") }
func childDidFinish<T>(result: T) { fatalError("Not Implemented but used") }
}
class TutorialRouter: Router {
private unowned let parentRouter: Router
private let device: Device
enum Result {
case cancelled
case completed
}
init(parentRouter: Router, device: Device) {
self.parentRouter = parentRouter
self.device = device
}
func start() {
// ...
}
func onLastStep() {
parentRouter.childDidFinish(result: Result.cancelled)
}
func onExit() {
parentRouter.childDidFinish(result: Result.completed)
}
}
class OnboardingRouter: Router {
private unowned let parentRouter: Router
enum Result {
case cancelled
case deviceOnboarded(Device)
}
init(parentRouter: Router) {
self.parentRouter = parentRouter
}
func start() {
// ...
}
func cancel() {
parentRouter.childDidFinish(result: Result.cancelled)
}
func onLastStep(with device: Device) {
parentRouter.childDidFinish(result: Result.deviceOnboarded(device))
}
}
class DashboardRouter: Router {
func start() {
let onboardingRouter = OnboardingRouter(parentRouter: self)
onboardingRouter.start()
}
func childDidFinish<T>(result: T) {
switch result {
case let onboarding as OnboardingRouter.Result:
handle(result: onboarding)
case let tutorial as TutorialRouter.Result:
handle(result: tutorial)
default:
fatalError("Missing handling for this child")
}
}
private func handle(result: OnboardingRouter.Result) {
switch result {
case .deviceOnboarded(let device):
let tutorialRouter = TutorialRouter(parentRouter: self, device: device)
tutorialRouter.start()
case .cancelled:
print("Nothing to do here/dismiss")
}
}
private func handle(result: TutorialRouter.Result) {
switch result {
case .completed:
print("Nothing to do here/dismiss")
case .cancelled:
print("Nothing to do here/dismiss")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment