public protocol Factory {
associatedtype ViewController: UIViewController
associatedtype Context
func build(with context: Context) throws -> ViewController
}
public protocol Factory {
associatedtype ViewController: UIViewController
associatedtype Context
func build(with context: Context) throws -> ViewController
}
public protocol Factory {
associatedtype ViewController: UIViewController
associatedtype Context
func build(with context: Context) throws -> ViewController
}
class ProductViewControllerFactory: Factory {
func build(with productID: UUID) throws -> ProductViewController {
let productViewController = ProductViewController(nibName: "ProductViewController", bundle: nil)
productViewController.productID = productID // In general it is better to do in in the `ContextAction`, but it will be described later.
return productViewController
class PresentModally: Action {
func perform(viewController: UIViewController, on existingController: UIViewController, animated: Bool, completion: @escaping (_: ActionResult) -> Void) {
guard existingController.presentedViewController == nil else {
completion(.failure("\(existingController) is already presenting a view controller."))
return
}
existingController.present(viewController, animated: animated, completion: {
public protocol Finder {
associatedtype ViewController: UIViewController
associatedtype Context
func findViewController(with context: Context) -> ViewController?
}
class ProductViewControllerFinder: StackIteratingFinder {
let options: SearchOptions
init(options: SearchOptions = .currentAndUp) {
self.options = options
}
func isTarget(_ productViewController: ProductViewController, with productID: UUID) -> Bool {
class LoginInterceptor: RoutingInterceptor {
func execute(for destination: AppDestination, completion: @escaping (_: InterceptorResult) -> Void) {
guard !LoginManager.sharedInstance.isUserLoggedIn else {
// ...
// Show LoginViewController and at the end of the logging in process call completion(.success) or completion(.failure("User has not been logged in."))
// ...
return
}
class ProductViewControllerContextTask: ContextTask {
func apply(on productViewController: ProductViewController, with productID: UUID) {
productViewController.productID = productID
}
}
class ProductViewControllerPostTask: PostRoutingTask {
let analyticsManager: AnalyticsManager
init(analyticsManager: AnalyticsManager) {
self.analyticsManager = analyticsManager
}
func execute(on productViewController: ProductViewController, for destination: AppDestination, routingStack: [UIViewController]) {
class ProductArrayViewController: UITableViewController {
let products: [UUID]?
// UITableViewControllerDelegate methods
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let productID = products[indexPath.row] else {
return