| 1 |
//
|
|
| 2 |
// RouteComposer
|
|
| 3 |
// StepAssembly.swift
|
|
| 4 |
// https://github.com/ekazaev/route-composer
|
|
| 5 |
//
|
|
| 6 |
// Created by Eugene Kazaev in 2018-2022.
|
|
| 7 |
// Distributed under the MIT license.
|
|
| 8 |
//
|
|
| 9 |
// Become a sponsor:
|
|
| 10 |
// https://github.com/sponsors/ekazaev
|
|
| 11 |
//
|
|
| 12 |
|
|
| 13 |
import Foundation
|
|
| 14 |
import UIKit
|
|
| 15 |
|
|
| 16 |
/// Builds a `DestinationStep` instance with the correct settings into a chain of steps.
|
|
| 17 |
/// ### NB
|
|
| 18 |
/// Both `Finder` and `Factory` instances should deal with the same type of `UIViewController` and `Context` instances.
|
|
| 19 |
/// ### Usage
|
|
| 20 |
/// ```swift
|
|
| 21 |
/// let productScreen = StepAssembly(finder: ProductViewControllerFinder(), factory: ProductViewControllerFactory())
|
|
| 22 |
/// .adding(LoginInterceptor())
|
|
| 23 |
/// .adding(ProductViewControllerContextTask())
|
|
| 24 |
/// .adding(ProductViewControllerPostTask(analyticsManager: AnalyticsManager.sharedInstance))
|
|
| 25 |
/// .using(UINavigationController.push())
|
|
| 26 |
/// .from(NavigationControllerStep())
|
|
| 27 |
/// .using(GeneralAction.presentModally())
|
|
| 28 |
/// .from(GeneralStep.current())
|
|
| 29 |
/// .assemble()
|
|
| 30 |
/// ```
|
|
| 31 |
public final class StepAssembly<F: Finder, FC: AbstractFactory>: GenericStepAssembly<F.ViewController, FC.Context>
|
|
| 32 |
where
|
|
| 33 |
F.ViewController == FC.ViewController, F.Context == FC.Context {
|
|
| 34 |
|
|
| 35 |
// MARK: Properties
|
|
| 36 |
|
|
| 37 |
let finder: F
|
|
| 38 |
|
|
| 39 |
let factory: FC
|
|
| 40 |
|
|
| 41 |
let previousSteps: [RoutingStep]
|
|
| 42 |
|
|
| 43 |
// MARK: Methods
|
|
| 44 |
|
|
| 45 |
private init(finder: F, abstractFactory: FC) {
|
194x |
| 46 |
self.factory = abstractFactory
|
194x |
| 47 |
self.finder = finder
|
194x |
| 48 |
self.previousSteps = []
|
194x |
| 49 |
}
|
194x |
| 50 |
|
|
| 51 |
}
|
|
| 52 |
|
|
| 53 |
// MARK: Methods for Factory
|
|
| 54 |
|
|
| 55 |
public extension StepAssembly where FC: Factory {
|
|
| 56 |
|
|
| 57 |
/// Constructor
|
|
| 58 |
///
|
|
| 59 |
/// - Parameters:
|
|
| 60 |
/// - finder: The `UIViewController` `Finder` instance.
|
|
| 61 |
/// - factory: The `UIViewController` `Factory` instance.
|
|
| 62 |
convenience init(finder: F, factory: FC) {
|
187x |
| 63 |
self.init(finder: finder, abstractFactory: factory)
|
187x |
| 64 |
}
|
187x |
| 65 |
|
|
| 66 |
/// Connects previously provided `DestinationStep` instance with an `Action`
|
|
| 67 |
///
|
|
| 68 |
/// - Parameter action: `Action` instance to be used with a step.
|
|
| 69 |
final func using(_ action: some Action) -> StepChainAssembly<ViewController, Context> {
|
71x |
| 70 |
var previousSteps = previousSteps
|
71x |
| 71 |
let entitiesCollector = BaseEntitiesCollector<FactoryBox<FC>, ActionBox>(finder: finder, factory: factory, action: action)
|
71x |
| 72 |
let step = BaseStep(entitiesProvider: entitiesCollector, taskProvider: taskCollector)
|
71x |
| 73 |
previousSteps.append(step)
|
71x |
| 74 |
return StepChainAssembly(previousSteps: previousSteps)
|
71x |
| 75 |
}
|
71x |
| 76 |
|
|
| 77 |
/// Connects previously provided `DestinationStep` instance with an `Action`
|
|
| 78 |
///
|
|
| 79 |
/// - Parameter action: `ContainerAction` instance to be used with a step.
|
|
| 80 |
final func using<A: ContainerAction>(_ action: A) -> ContainerStepChainAssembly<A.ViewController, ViewController, Context> {
|
54x |
| 81 |
var previousSteps = previousSteps
|
54x |
| 82 |
let entitiesCollector = BaseEntitiesCollector<FactoryBox<FC>, ContainerActionBox>(finder: finder, factory: factory, action: action)
|
54x |
| 83 |
let step = BaseStep(entitiesProvider: entitiesCollector, taskProvider: taskCollector)
|
54x |
| 84 |
previousSteps.append(step)
|
54x |
| 85 |
return ContainerStepChainAssembly(previousSteps: previousSteps)
|
54x |
| 86 |
}
|
54x |
| 87 |
|
|
| 88 |
}
|
|
| 89 |
|
|
| 90 |
// MARK: Methods for ContainerFactory
|
|
| 91 |
|
|
| 92 |
public extension StepAssembly where FC: ContainerFactory {
|
|
| 93 |
|
|
| 94 |
/// Constructor
|
|
| 95 |
///
|
|
| 96 |
/// - Parameters:
|
|
| 97 |
/// - finder: The `UIViewController` `Finder` instance.
|
|
| 98 |
/// - factory: The `UIViewController` `ContainerFactory` instance.
|
|
| 99 |
convenience init(finder: F, factory: FC) {
|
7x |
| 100 |
self.init(finder: finder, abstractFactory: factory)
|
7x |
| 101 |
}
|
7x |
| 102 |
|
|
| 103 |
/// Connects previously provided `DestinationStep` instance with an `Action`
|
|
| 104 |
///
|
|
| 105 |
/// - Parameter action: `Action` instance to be used with a step.
|
|
| 106 |
final func using(_ action: some Action) -> StepChainAssembly<ViewController, Context> {
|
1x |
| 107 |
var previousSteps = previousSteps
|
1x |
| 108 |
let entitiesCollector = BaseEntitiesCollector<ContainerFactoryBox<FC>, ActionBox>(finder: finder, factory: factory, action: action)
|
1x |
| 109 |
let step = BaseStep(entitiesProvider: entitiesCollector, taskProvider: taskCollector)
|
1x |
| 110 |
previousSteps.append(step)
|
1x |
| 111 |
return StepChainAssembly(previousSteps: previousSteps)
|
1x |
| 112 |
}
|
1x |
| 113 |
|
|
| 114 |
/// Connects previously provided `DestinationStep` instance with an `Action`
|
|
| 115 |
///
|
|
| 116 |
/// - Parameter action: `ContainerAction` instance to be used with a step.
|
|
| 117 |
final func using<A: ContainerAction>(_ action: A) -> ContainerStepChainAssembly<A.ViewController, ViewController, Context> {
|
4x |
| 118 |
var previousSteps = previousSteps
|
4x |
| 119 |
let entitiesCollector = BaseEntitiesCollector<ContainerFactoryBox<FC>, ContainerActionBox>(finder: finder, factory: factory, action: action)
|
4x |
| 120 |
let step = BaseStep(entitiesProvider: entitiesCollector, taskProvider: taskCollector)
|
4x |
| 121 |
previousSteps.append(step)
|
4x |
| 122 |
return ContainerStepChainAssembly(previousSteps: previousSteps)
|
4x |
| 123 |
}
|
4x |
| 124 |
}
|
|
| 125 |
|
|
| 126 |
// MARK: Methods for the Nil Factory
|
|
| 127 |
|
|
| 128 |
public extension StepAssembly where FC: Factory & NilEntity {
|
|
| 129 |
|
|
| 130 |
/// Connects previously provided `ActionToStepIntegrator` with `NilEntity` factory with a step where the `UIViewController`
|
|
| 131 |
/// should avoid type checks
|
|
| 132 |
/// Example: `UIViewController` instance was loaded as a part of the stack inside of the storyboard.
|
|
| 133 |
///
|
|
| 134 |
/// - Parameter step: `ActionToStepIntegrator` instance to be used.
|
|
| 135 |
final func from(_ step: ActionToStepIntegrator<some UIViewController, Context>) -> ActionConnectingAssembly<ViewController, Context> {
|
8x |
| 136 |
var previousSteps = previousSteps
|
8x |
| 137 |
let entitiesCollector = BaseEntitiesCollector<FactoryBox<FC>, ActionBox>(finder: finder, factory: factory, action: ViewControllerActions.NilAction())
|
8x |
| 138 |
let currentStep = BaseStep(entitiesProvider: entitiesCollector, taskProvider: taskCollector)
|
8x |
| 139 |
previousSteps.append(currentStep)
|
8x |
| 140 |
return ActionConnectingAssembly(stepToFullFill: step, previousSteps: previousSteps)
|
8x |
| 141 |
}
|
8x |
| 142 |
|
|
| 143 |
/// Connects previously provided `DestinationStep` with `NilEntity` factory with a step where the `UIViewController`
|
|
| 144 |
/// should avoid type checks
|
|
| 145 |
/// Example: `UIViewController` instance was loaded as a part of the stack inside of the storyboard.
|
|
| 146 |
///
|
|
| 147 |
/// - Parameter step: `DestinationStep` instance to be used.
|
|
| 148 |
final func from(_ step: DestinationStep<some UIViewController, Context>) -> LastStepInChainAssembly<ViewController, Context> {
|
54x |
| 149 |
var previousSteps = previousSteps
|
54x |
| 150 |
let entitiesCollector = BaseEntitiesCollector<FactoryBox<FC>, ActionBox>(finder: finder, factory: factory, action: ViewControllerActions.NilAction())
|
54x |
| 151 |
let currentStep = BaseStep(entitiesProvider: entitiesCollector, taskProvider: taskCollector)
|
54x |
| 152 |
previousSteps.append(currentStep)
|
54x |
| 153 |
previousSteps.append(step)
|
54x |
| 154 |
return LastStepInChainAssembly(previousSteps: previousSteps)
|
54x |
| 155 |
}
|
54x |
| 156 |
|
|
| 157 |
}
|
|
| 158 |
|
|
| 159 |
// MARK: Methods for the Nil ConatinerFactory
|
|
| 160 |
|
|
| 161 |
public extension StepAssembly where FC: ContainerFactory & NilEntity {
|
|
| 162 |
|
|
| 163 |
/// Connects previously provided `ActionToStepIntegrator` with `NilEntity` factory with a step where the `UIViewController`
|
|
| 164 |
/// should avoid type checks.
|
|
| 165 |
///
|
|
| 166 |
/// - Parameter step: `ActionToStepIntegrator` instance to be used.
|
|
| 167 |
final func from(_ step: ActionToStepIntegrator<some UIViewController, Context>) -> ActionConnectingAssembly<ViewController, Context> {
|
1x |
| 168 |
var previousSteps = previousSteps
|
1x |
| 169 |
let entitiesCollector = BaseEntitiesCollector<ContainerFactoryBox<FC>, ActionBox>(finder: finder, factory: factory, action: ViewControllerActions.NilAction())
|
1x |
| 170 |
let currentStep = BaseStep(entitiesProvider: entitiesCollector, taskProvider: taskCollector)
|
1x |
| 171 |
previousSteps.append(currentStep)
|
1x |
| 172 |
return ActionConnectingAssembly(stepToFullFill: step, previousSteps: previousSteps)
|
1x |
| 173 |
}
|
1x |
| 174 |
|
|
| 175 |
/// Connects previously provided `DestinationStep` with `NilEntity` factory with a step where the `UIViewController`
|
|
| 176 |
/// should avoid type checks
|
|
| 177 |
///
|
|
| 178 |
/// - Parameter step: `DestinationStep` instance to be used.
|
|
| 179 |
final func from(_ step: DestinationStep<some UIViewController, Context>) -> LastStepInChainAssembly<ViewController, Context> {
|
1x |
| 180 |
var previousSteps = previousSteps
|
1x |
| 181 |
let entitiesCollector = BaseEntitiesCollector<ContainerFactoryBox<FC>, ActionBox>(finder: finder, factory: factory, action: ViewControllerActions.NilAction())
|
1x |
| 182 |
let currentStep = BaseStep(entitiesProvider: entitiesCollector, taskProvider: taskCollector)
|
1x |
| 183 |
previousSteps.append(currentStep)
|
1x |
| 184 |
previousSteps.append(step)
|
1x |
| 185 |
return LastStepInChainAssembly(previousSteps: previousSteps)
|
1x |
| 186 |
}
|
1x |
| 187 |
|
|
| 188 |
}
|
|