Root
import RIBs
protocol RootInteractable: Interactable, LoggedOutListener, NavigationListener {
var router: RootRouting? { get set }
var listener: RootListener? { get set }
}
protocol RootViewControllable: ViewControllable {
func present(viewController: ViewControllable)
func dismiss(viewController: ViewControllable)
}
final class RootRouter: LaunchRouter<RootInteractable, RootViewControllable>, RootRouting {
init(interactor: RootInteractable, viewController: RootViewControllable, loggedOutBuilder: LoggedOutBuildable, navigationBuilder: NavigationBuildable) {
self.loggedOutBuilder = loggedOutBuilder
self.navigationBuilder = navigationBuilder
super.init(interactor: interactor, viewController: viewController)
interactor.router = self
}
override func didLoad() {
super.didLoad()
routeToLoggedOut()
}
// MARK: - RootRouting
func routeToNavigation() {
if let loggedOut = loggedOut {
detachChild(loggedOut)
if let navigationController = loggedOut.viewControllable.uiviewController.navigationController {
viewController.dismiss(viewController: navigationController)
} else {
viewController.dismiss(viewController: loggedOut.viewControllable)
}
self.loggedOut = nil
}
let navigation = navigationBuilder.build(withListener: interactor)
self.navigation = navigation
attachChild(navigation)
}
// MARK: - Private
private let navigationBuilder: NavigationBuildable
private let loggedOutBuilder: LoggedOutBuildable
private var navigation: NavigationRouting?
private var loggedOut: LoggedOutRouting?
private func routeToLoggedOut() {
let loggedOut = loggedOutBuilder.build(withListener: interactor)
self.loggedOut = loggedOut
attachChild(loggedOut)
viewController.present(viewController: loggedOut.viewControllable)
}
}
import RIBs
import RxSwift
import UIKit
protocol RootPresentableListener: AnyObject {
// TODO: Declare properties and methods that the view controller can invoke to perform
// business logic, such as signIn(). This protocol is implemented by the corresponding
// interactor class.
}
final class RootViewController: UIViewController, RootPresentable, RootViewControllable {
weak var listener: RootPresentableListener?
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("Method is not supported")
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
}
// MARK: - RootViewControllable
func present(viewController: ViewControllable) {
viewController.uiviewController.modalPresentationStyle = .fullScreen
present(viewController.uiviewController, animated: true, completion: nil)
}
func dismiss(viewController: ViewControllable) {
if presentedViewController === viewController.uiviewController {
dismiss(animated: true, completion: nil)
}
}
}
// MARK: NavigationViewControllable
extension RootViewController: NavigationViewControllable {
func push(viewController: RIBs.ViewControllable) {
uiviewController.navigationController?.pushViewController(viewController.uiviewController, animated: true)
}
}
import RIBs
protocol RootDependency: Dependency {
// TODO: Declare the set of dependencies required by this RIB, but cannot be
// created by this RIB.
}
final class RootComponent: Component<RootDependency>, NavigationDependency {
var navigationController: NavigationViewControllable {
return rootViewController
}
let rootViewController: RootViewController
init(dependency: RootDependency, rootViewController: RootViewController) {
self.rootViewController = rootViewController
super.init(dependency: dependency)
}
}
// MARK: - Builder
protocol RootBuildable: Buildable {
func build() -> LaunchRouting
}
final class RootBuilder: Builder<RootDependency>, RootBuildable {
override init(dependency: RootDependency) {
super.init(dependency: dependency)
}
func build() -> LaunchRouting {
let viewController = RootViewController()
let component = RootComponent(dependency: dependency, rootViewController: viewController)
let interactor = RootInteractor(presenter: viewController)
let loggedOutBuilder = LoggedOutBuilder(dependency: component)
let navigationBuilder = NavigationBuilder(dependency: component)
return RootRouter(interactor: interactor, viewController: viewController, loggedOutBuilder: loggedOutBuilder, navigationBuilder: navigationBuilder)
}
}
import RIBs
import RxSwift
protocol RootRouting: ViewableRouting {
func routeToNavigation()
}
protocol RootPresentable: Presentable {
var listener: RootPresentableListener? { get set }
// TODO: Declare methods the interactor can invoke the presenter to present data.
}
protocol RootListener: AnyObject {
// TODO: Declare methods the interactor can invoke to communicate with other RIBs.
}
final class RootInteractor: PresentableInteractor<RootPresentable>, RootInteractable, RootPresentableListener {
weak var router: RootRouting?
weak var listener: RootListener?
// TODO: Add additional dependencies to constructor. Do not perform any logic
// in constructor.
override init(presenter: RootPresentable) {
super.init(presenter: presenter)
presenter.listener = self
}
override func didBecomeActive() {
super.didBecomeActive()
// TODO: Implement business logic here.
}
override func willResignActive() {
super.willResignActive()
// TODO: Pause any business logic.
}
// MARK: - LoggedOutListener
func didTappedNavigation() {
router?.routeToNavigation()
}
}
import RIBs
extension RootComponent: LoggedOutDependency {
// TODO: Implement properties to provide for LoggedOut scope.
}
LoggedOut
import RIBs
protocol LoggedOutInteractable: Interactable {
var router: LoggedOutRouting? { get set }
var listener: LoggedOutListener? { get set }
}
protocol LoggedOutViewControllable: ViewControllable {
// TODO: Declare methods the router invokes to manipulate the view hierarchy.
}
final class LoggedOutRouter: ViewableRouter<LoggedOutInteractable, LoggedOutViewControllable>, LoggedOutRouting {
// TODO: Constructor inject child builder protocols to allow building children.
override init(interactor: LoggedOutInteractable, viewController: LoggedOutViewControllable) {
super.init(interactor: interactor, viewController: viewController)
interactor.router = self
}
}
import RIBs
import RxCocoa
import RxSwift
import UIKit
import SnapKit
protocol LoggedOutPresentableListener: AnyObject {
func didTappedNavigationButton()
}
final class LoggedOutViewController: UIViewController, LoggedOutPresentable, LoggedOutViewControllable {
weak var listener: LoggedOutPresentableListener?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.purple
buildRouterAButton()
}
// MARK: - Private
private func buildRouterAButton() {
let aButton = UIButton()
view.addSubview(aButton)
aButton.snp.makeConstraints { (maker: ConstraintMaker) in
maker.centerX.centerY.equalToSuperview()
}
aButton.setTitle("navigation RIB으로 이동할까?", for: .normal)
aButton.setTitleColor(UIColor.white, for: .normal)
aButton.backgroundColor = UIColor.black
aButton.rx.tap
.subscribe(onNext: { [weak self] in
self?.listener?.didTappedNavigationButton()
})
.disposed(by: disposeBag)
}
private let disposeBag = DisposeBag()
}
import RIBs
protocol LoggedOutDependency: Dependency {
// TODO: Declare the set of dependencies required by this RIB, but cannot be
// created by this RIB.
}
final class LoggedOutComponent: Component<LoggedOutDependency> {
// TODO: Declare 'fileprivate' dependencies that are only used by this RIB.
}
// MARK: - Builder
protocol LoggedOutBuildable: Buildable {
func build(withListener listener: LoggedOutListener) -> LoggedOutRouting
}
final class LoggedOutBuilder: Builder<LoggedOutDependency>, LoggedOutBuildable {
override init(dependency: LoggedOutDependency) {
super.init(dependency: dependency)
}
func build(withListener listener: LoggedOutListener) -> LoggedOutRouting {
let component = LoggedOutComponent(dependency: dependency)
let viewController = LoggedOutViewController()
let interactor = LoggedOutInteractor(presenter: viewController)
interactor.listener = listener
return LoggedOutRouter(interactor: interactor, viewController: viewController)
}
}
import RIBs
import RxSwift
protocol LoggedOutRouting: ViewableRouting {
// TODO: Declare methods the interactor can invoke to manage sub-tree via the router.
}
protocol LoggedOutPresentable: Presentable {
var listener: LoggedOutPresentableListener? { get set }
// TODO: Declare methods the interactor can invoke the presenter to present data.
}
protocol LoggedOutListener: AnyObject {
func didTappedNavigation()
}
final class LoggedOutInteractor: PresentableInteractor<LoggedOutPresentable>, LoggedOutInteractable, LoggedOutPresentableListener {
weak var router: LoggedOutRouting?
weak var listener: LoggedOutListener?
// TODO: Add additional dependencies to constructor. Do not perform any logic
// in constructor.
override init(presenter: LoggedOutPresentable) {
super.init(presenter: presenter)
presenter.listener = self
}
override func didBecomeActive() {
super.didBecomeActive()
// TODO: Implement business logic here.
}
override func willResignActive() {
super.willResignActive()
// TODO: Pause any business logic.
}
// MARK: - LoggedOutPresentableListener
func didTappedNavigationButton() {
listener?.didTappedNavigation()
}
}
Navigation
import RIBs
protocol NavigationInteractable: Interactable, NavigationAListener {
var router: NavigationRouting? { get set }
var listener: NavigationListener? { get set }
}
protocol NavigationViewControllable: ViewControllable {
func present(viewController: ViewControllable)
func dismiss(viewController: ViewControllable)
func push(viewController: ViewControllable)
}
final class NavigationRouter: ViewableRouter<NavigationInteractable, NavigationViewControllable>, NavigationRouting {
// TODO: Constructor inject child builder protocols to allow building children.
init(interactor: NavigationInteractable, viewController: NavigationViewControllable, navigationABuilder: NavigationABuildable) {
self.navigationABuilder = navigationABuilder
super.init(interactor: interactor, viewController: viewController)
interactor.router = self
}
override func didLoad() {
super.didLoad()
routeToNavigationA()
}
private let navigationABuilder: NavigationABuildable
private var navigationA: NavigationARouting?
func routeToNavigationA() {
let navigationA = navigationABuilder.build(withListener: interactor)
self.navigationA = navigationA
attachChild(navigationA)
let navigationController = UINavigationController(root: navigationA.viewControllable)
viewController.present(viewController: navigationController)
}
}
import RIBs
protocol NavigationDependency: Dependency {
// TODO: Declare the set of dependencies required by this RIB, but cannot be
var navigationController: NavigationViewControllable { get }
}
final class NavigationComponent: Component<NavigationDependency> {
fileprivate var navigationController: NavigationViewControllable {
return dependency.navigationController
}
}
// MARK: - Builder
protocol NavigationBuildable: Buildable {
func build(withListener listener: NavigationListener) -> NavigationRouting
}
final class NavigationBuilder: Builder<NavigationDependency>, NavigationBuildable {
override init(dependency: NavigationDependency) {
super.init(dependency: dependency)
}
func build(withListener listener: NavigationListener) -> NavigationRouting {
let component = NavigationComponent(dependency: dependency)
let interactor = NavigationInteractor()
interactor.listener = listener
let aBuilder = NavigationABuilder(dependency: component)
return NavigationRouter(interactor: interactor, viewController: component.navigationController, navigationABuilder: aBuilder )
}
}
import RIBs
import RxSwift
protocol NavigationRouting: ViewableRouting {
// func routeToNavigationA()
}
protocol NavigationListener: AnyObject {
// TODO: Declare methods the interactor can invoke to communicate with other RIBs.
}
final class NavigationInteractor: Interactor, NavigationInteractable {
weak var router: NavigationRouting?
weak var listener: NavigationListener?
override func didBecomeActive() {
super.didBecomeActive()
// TODO: Implement business logic here.
}
override func willResignActive() {
super.willResignActive()
// TODO: Pause any business logic.
}
}
import RIBs
extension NavigationComponent: NavigationADependency {
// TODO: Implement properties to provide for LoggedOut scope.
}
NavigationA
import RIBs
protocol NavigationAInteractable: Interactable {
var router: NavigationARouting? { get set }
var listener: NavigationAListener? { get set }
}
protocol NavigationAViewControllable: ViewControllable {
// TODO: Declare methods the router invokes to manipulate the view hierarchy.
}
final class NavigationARouter: ViewableRouter<NavigationAInteractable, NavigationAViewControllable>, NavigationARouting {
// TODO: Constructor inject child builder protocols to allow building children.
override init(interactor: NavigationAInteractable, viewController: NavigationAViewControllable) {
super.init(interactor: interactor, viewController: viewController)
interactor.router = self
}
}
import RIBs
import RxSwift
import UIKit
protocol NavigationAPresentableListener: AnyObject {
// TODO: Declare properties and methods that the view controller can invoke to perform
// business logic, such as signIn(). This protocol is implemented by the corresponding
// interactor class.
}
final class NavigationAViewController: UIViewController, NavigationAPresentable, NavigationAViewControllable {
weak var listener: NavigationAPresentableListener?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.blue
setNavigationBar()
}
// MARK: - Private
private func setNavigationBar() {
self.navigationItem.title = "Navigation A로 이동함"
self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
}
}
import RIBs
protocol NavigationADependency: Dependency {
// TODO: Declare the set of dependencies required by this RIB, but cannot be
// created by this RIB.
}
final class NavigationAComponent: Component<NavigationADependency> {
// TODO: Declare 'fileprivate' dependencies that are only used by this RIB.
}
// MARK: - Builder
protocol NavigationABuildable: Buildable {
func build(withListener listener: NavigationAListener) -> NavigationARouting
}
final class NavigationABuilder: Builder<NavigationADependency>, NavigationABuildable {
override init(dependency: NavigationADependency) {
super.init(dependency: dependency)
}
func build(withListener listener: NavigationAListener) -> NavigationARouting {
let component = NavigationAComponent(dependency: dependency)
let viewController = NavigationAViewController()
let interactor = NavigationAInteractor(presenter: viewController)
interactor.listener = listener
return NavigationARouter(interactor: interactor, viewController: viewController)
}
}
import RIBs
import RxSwift
protocol NavigationARouting: ViewableRouting {
// TODO: Declare methods the interactor can invoke to manage sub-tree via the router.
}
protocol NavigationAPresentable: Presentable {
var listener: NavigationAPresentableListener? { get set }
// TODO: Declare methods the interactor can invoke the presenter to present data.
}
protocol NavigationAListener: AnyObject {
// TODO: Declare methods the interactor can invoke to communicate with other RIBs.
}
final class NavigationAInteractor: PresentableInteractor<NavigationAPresentable>, NavigationAInteractable, NavigationAPresentableListener {
weak var router: NavigationARouting?
weak var listener: NavigationAListener?
// TODO: Add additional dependencies to constructor. Do not perform any logic
// in constructor.
override init(presenter: NavigationAPresentable) {
super.init(presenter: presenter)
presenter.listener = self
}
override func didBecomeActive() {
super.didBecomeActive()
// TODO: Implement business logic here.
}
override func willResignActive() {
super.willResignActive()
// TODO: Pause any business logic.
}
}