Skip to content

Instantly share code, notes, and snippets.

@simme
Last active September 10, 2020 00:51
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save simme/ea0918d534f13ace3445e84ec043ed99 to your computer and use it in GitHub Desktop.
Save simme/ea0918d534f13ace3445e84ec043ed99 to your computer and use it in GitHub Desktop.
/**
A default implmentation that provides a few convenience methods for starting and stopping coordinators.
*/
extension Coordinator {
// Default implementation, so that we don't have to do this for all coordinators.
func startChild<T: NSObject where T: Coordinator>(coordinator coordinator: T, withIdentifier identifier: String, callback: CoordinatorCallback?) -> T {
childCoordinators[identifier] = coordinator
coordinator.start(withCallback: callback)
return coordinator
}
func stop(coordinatorWithIdentifier identifier: String, callback: CoordinatorCallback? = nil) {
guard let coordinator = childCoordinators[identifier] as? Coordinator, let index = childCoordinators.indexForKey(identifier) else {
fatalError("No such coordinator: \(identifier)")
}
coordinator.stop(withCallback: { [unowned self] (coordinator) in
self.childCoordinators.removeAtIndex(index)
callback?(coordinator)
})
}
/**
Start a child coordinator of the inferred type and store a reference to ti.
- Parameter rootViewController: The root view controller of the new child coordinator.
- Parameter configure: An optional configuraiton block
*/
func startChildWith<T: NSObject where T: Coordinator>(rootViewController: UIViewController, callback: CoordinatorCallback? = nil, configureWith configurationBlock: ((T) -> Void)? = nil) -> T {
let coordinator = T.init(appContext: appContext, storyboard: storyboard, rootViewController: rootViewController)
configurationBlock?(coordinator)
startChild(coordinator: coordinator, withIdentifier: coordinator.identifier, callback: callback)
return coordinator
}
}
//
// Coordinator.swift
//
// License: MIT
// Author: Simon Ljungberg, Filibaba
//
import UIKit
/// A callack function used by coordinators to signal events.
typealias CoordinatorCallback = (Coordinator) -> Void
/**
A coordinator is an object that manages the flow and life cycle of view controllers in an application.
See: http://khanlou.com/2015/10/coordinators-redux/ for more.
*/
protocol Coordinator: NSObjectProtocol {
/// A string that identifies this coordinator.
var identifier: String { get set }
/// Some object holding information about the application context. Database references, user settings etc.
var appContext: AppContext? { get }
/// The storyboard we create new view controllers from. Not using segues, only storyboard identifiers.
var storyboard: UIStoryboard { get }
/// The root view controller for a coordinator.
var rootViewController: UIViewController { get }
// We identify each coordinator with a string, for debugging reasons and stuff.
var childCoordinators: [String: NSObject] { get set }
/// Force a uniform initializer on our implementors.
init(appContext: AppContext?, storyboard: UIStoryboard, rootViewController: UIViewController)
/// Tells the coordinator to create its initial view controller and take over the user flow.
func start(withCallback completion: CoordinatorCallback?)
/// Tells the coordinator that it is done and that it should rewind the view controller state to where it was before `start` was called.
func stop(withCallback completion: CoordinatorCallback?)
/**
Add a new child coordinator and start it.
- Parameter coordinator: The coordinator implementation to start.
- Parameter identifier: A string identifiying this particular coordinator.
- Parameter callback: An optional `CoordinatorCallback` passed to the coordinator's `start()` method.
- Returns: The started coordinator.
*/
func startChild<T: NSObject where T: Coordinator>(coordinator coordinator: T, withIdentifier identifier: String, callback: CoordinatorCallback?) -> T
/**
Stops the coordinator and removes our reference to it.
- Parameter identifier: The string identifier of the coordinator to stop.
- Parameter callback: An optional `CoordinatorCallback` passed to the coordinator's `stop()` method.
*/
func stop(coordinatorWithIdentifier identifier: String, callback: CoordinatorCallback?)
}
@Burgestrand
Copy link

Burgestrand commented Dec 20, 2016

Off-topic, I'm sorry.

Here I am, casually reading random blog posts on iOS development, going about my daily business. Short googling and I came across this gist, created a mere 4 days ago. Some very old bell rings, and I think to myself I know this github username.

Lo and behold, phpportalen 7 years ago.

I found this a fun coincidence. The world isn't always big. :)

@simme
Copy link
Author

simme commented Aug 9, 2017

@Burgestrand: GitHub notifications suck.
*more than a year later:
Recognized your name too the moment I saw it! :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment