Created
June 13, 2018 13:45
-
-
Save libdx/745b576030bccd91c4f52f080c0cad23 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Abstract interface | |
protocol Interactor: class { | |
associatedtype Action | |
func dispatch(action: Action) | |
init() | |
} | |
protocol Presenter: class { | |
associatedtype State | |
var sendState: ((State) -> ())! { get set } | |
init() | |
} | |
protocol Component /* aka View */ : class { | |
associatedtype State | |
associatedtype P: Presenter | |
associatedtype I: Interactor | |
func didReceiveNewState(_ state: State) | |
var presenter: P! { get set } | |
var interactor: I! { get set } | |
init() | |
} | |
// Specific scene (module, component) | |
enum ABCAction /* aka Request */ { | |
} | |
struct ABCLoadedState { | |
var title: String | |
} | |
enum ABCState { | |
case initial | |
case loading | |
case loaded(value: ABCLoadedState) | |
} | |
final class ABCPresenter: Presenter { | |
typealias State = ABCState | |
var sendState: ((State) -> ())! | |
init() {} | |
} | |
final class ABCInteractor: Interactor { | |
typealias Action = ABCAction | |
func dispatch(action: Action) { | |
} | |
init() {} | |
} | |
final class ABCViewController<I: Interactor, P: Presenter>: UIViewController, Component { | |
typealias State = P.State | |
var state: ABCState = .initial | |
var presenter: P! | |
var interactor: I! | |
func didReceiveNewState(_ state: State) { | |
} | |
} | |
// Generic factory function | |
func makeComponent<C: Component>() -> C where C.State == C.P.State, C: UIViewController { | |
let interactor = C.I() | |
let presenter = C.P() | |
let viewController = C() | |
viewController.presenter = presenter | |
viewController.interactor = interactor | |
// Having `sendState` closure prevents having unresolvable cycled dependency with generics | |
presenter.sendState = { [weak viewController] state in | |
viewController?.didReceiveNewState(state) | |
} | |
return viewController | |
} | |
// `makeComponent` usage example | |
func makeABCViewController() -> ABCViewController<ABCInteractor, ABCPresenter> { | |
return makeComponent() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment