Architecture (swift)/RIBs
[iOS - swift] 4-3) RIBs 튜토리얼 (viewless RIB)
jake-kim
2021. 4. 20. 00:45

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

- 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 }
}
* 참고