관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 4-3) RIBs 튜토리얼 (viewless RIB) 본문

Architecture (swift)/RIBs

[iOS - swift] 4-3) RIBs 튜토리얼 (viewless RIB)

jake-kim 2021. 4. 20. 00:45

RIB 트리

RIB 라우팅 (LoggedOut -> LoggedIn)

  • RootRouting protocol에 LoggedIn RIB으로 화면전환 관련 함수 선언
// RootInteractor.swift

protocol RootRouting: ViewableRouting {
    func routeToLoggedIn(withPlayer1Name player1Name: String, player2Name: String)
}
  • LoggedOutListener를 통해서 RootInteractor에 didLogin 이벤트를 받은 경우, 화면전환
// RootInteractor.swift

    func didLogin(player1Name: String, player2Name: String) {
        router?.routeToLoggedIn(withPlayer1Name: player1Name, player2Name: player2Name)
    }

RootRouting구현 강제

  • LoggedIn RIB 생성: viewless인 RIB이므로 생성 시 설정 필요
    • Owns corresponding view 체크 해제

LoggedIn 빌더 파일 세팅

  • RootRouter -> attach LoggedIn
    • 새로 추가될 LoggedIn RIB의 Buildable을 RootRouter의 프로퍼티에 추가, 초기화 적용
// RootRouter.swift 
private let loggedInBuilder: LoggedInBuildable
…
init(interactor: RootInteractable,
         viewController: RootViewControllable,
         loggedOutBuilder: LoggedOutBuildable,
         loggedInBuilder: LoggedInBuildable) {
        self.loggedOutBuilder = loggedOutBuilder
        self.loggedInBuilder = loggedInBuilder
        super.init(interactor: interactor, viewController: viewController)
        interactor.router = self
    }
  • RootRouter생성자를 반환하고 있는 RootBuilder에도 반영
    func build() -> LaunchRouting {
        let viewController = RootViewController()
        let component = RootComponent(dependency: dependency,
                                      rootViewController: viewController)
        let interactor = RootInteractor(presenter: viewController)

        let loggedOutBuilder = LoggedOutBuilder(dependency: component)
        let loggedInBuilder = LoggedInBuilder(dependency: component)

        return RootRouter(interactor: interactor,
                          viewController: viewController,
                          loggedOutBuilder: loggedOutBuilder,
                          loggedInBuilder: loggedInBuilder)
    }
  • 위에서 LoggedInBuilder(dependency:) 인자에 RootViewController속성인 component를 넘기므로, 빌드오류
    - RootViewController에서 extension으로 LoggedInViewController 구현
// RootViewController.swift

// MARK: LoggedInViewControllable

extension RootViewController: LoggedInViewControllable {

}
  • 프로젝트가 만들어질때 PaskalCase로 선언 되었지만 camelCase로 구현되어 있는 부분 오타 수정
// RootComponent+LoggedIn.swift

extension RootComponent: LoggedInDependency {
    var LoggedInViewController: LoggedInViewControllable {
        return rootViewController
    }
}

detach LoggedOut, attach LoggedIn

  • RootRoter.swift에서 dismiss하는 기능 추가
// RootRouter.swift

protocol RootViewControllable: ViewControllable {
    func present(viewController: ViewControllable)
    func dismiss(viewController: ViewControllable) // <- 추가
}
  • RootViewController.swift에서 구현
// RootViewController.swift
    func dismiss(viewController: ViewControllable) {
        if presentedViewController === viewController.uiviewController {
            dismiss(animated: true, completion: nil)
        }
    }
  • detach, attach하는 쪽은 부모인 RootRouter.swift, 이를 호출하는 곳은 RootInteractor
// RootRouter.swift
    func routeToLoggedIn(withPlayer1Name player1Name: String, player2Name: String) {
        if let loggedOut = self.loggedOut {
            detachChild(loggedOut)
            viewController.dismiss(viewConroller: loggedOut.viewControllable)
            self.loggedOut = nil
        }
        let loggedIn = loggedInBuilder.build(withListener: interactor)
        attachChild(loggedIn)
    }
  • 위에서 listener의 객체 interactor를 주입할 경우, RootInteractable은 LoggedInlistener의 타입을 갖고 있지 않으므로 아래와 같이 LoggedInListener 구현
// RootRouter.swift
protocol RootInteractable: Interactable, LoggedOutListener, LoggedInListener {
    weak var router: RootRouting? { get set }
    weak var listener: RootListener? { get set }
}

 

* 참고

github.com/uber/RIBs/wiki/iOS-Tutorial-2

Comments