Skip to content

Instantly share code, notes, and snippets.

@libdx
Created June 13, 2018 13:45
Show Gist options
  • Save libdx/745b576030bccd91c4f52f080c0cad23 to your computer and use it in GitHub Desktop.
Save libdx/745b576030bccd91c4f52f080c0cad23 to your computer and use it in GitHub Desktop.
// 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