RIBs example

hyun·2023년 12월 25일
0

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()
    }
}
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.
}
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.
    }
}

0개의 댓글