관리 메뉴

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

[iOS - swift] 4-4) RIBs 튜토리얼 (LoggedIn에 OffGame 붙이기) 본문

Architecture (swift)/RIBs

[iOS - swift] 4-4) RIBs 튜토리얼 (LoggedIn에 OffGame 붙이기)

jake-kim 2021. 4. 21. 23:33

LoggedIn에 OffGame 붙이기, 이동

RIB 트리

OffGame 생성

부모인 LoggedIn에 OffGame Builder 프로퍼티 추가

  • Router에 새로운 Builder 프로퍼티 추가
// LoggedInRouter.swift

private let offGameBuilder: OffGameBuildable

init(interactor: LoggedInInteractable,
     viewController: LoggedInViewControllable,
     offGameBuilder: OffGameBuildable) {
    self.viewController = viewController
    self.offGameBuilder = offGameBuilder
    super.init(interactor: interactor)
    interactor.router = self
}
  • Builder에 변경된 Router내용 적용
// LoggedInBuilder.swift

func build(withListener listener: LoggedInListener) -> LoggedInRouting {
    let component = LoggedInComponent(dependency: dependency)
    let interactor = LoggedInInteractor()
    interactor.listener = listener

    let offGameBuilder = OffGameBuilder(dependency: component)
    return LoggedInRouter(interactor: interactor,
                          viewController: component.loggedInViewController,
                          offGameBuilder: offGameBuilder)
}

  • LoggedInComponent+OffGame 생성하여 LoggedinComponent에 OffGameComponent속성 구현

attach, detach 처리

  • LoggedIn에서 로그인이 성공하면 offGame이 바로 나와야 하므로, LoggedIn이 didLoad되었을 경우 attach OffGame 하도록 준비
// LoggedInRouter.swift
    override func didLoad() {
        super.didLoad()
        attachOffGame()
    }
  • attachOffGame() 구현, child참조하고 있는 변수 선언
// LoggedInRouter.swift
private var currentChild: ViewableRouting?

private func attachOffGame() {
    let offGame = offGameBuilder.build(withListener: interactor)
    self.currentChild = offGame
    attachChild(offGame)
    viewController.present(viewController: offGame.viewControllable)
}

 

 

  • LoggedInInterctable에 OffGameListener 프로토콜 구현
// LoggedInRouter.swift

protocol LoggedInInteractable: Interactable, OffGameListener {
    var router: LoggedInRouting? { get set }
    var listener: LoggedInListener? { get set }
}

  • present 기능 추가
    - 구현은 RootViewController에서 되어 있으므로, protocol에만 명시하면 가능
    - LoggedIn은 viewless이지만 Router에 존재하는 ViewControllable프로토콜을 사용하여 해결
    - RootViewController가 LoggedInViewControllable을 구현하고 있으므로 프로토콜 선언만 하면 가능
// LoggedInRouter.swift

protocol LoggedInViewControllable: ViewControllable {
    func present(viewController: ViewControllable)
    func dismiss(viewController: ViewControllable)
}
  • LoggedIn이 detach될 때 LoggedIn의 자식을 dismiss하는 기능
    - 호출은 LoggedInInteractor에서 수행
// LoggedInRouter.swift

func cleanupViews() {
    if let currentChild = currentChild {
        viewController.dismiss(viewController: currentChild.viewControllable)
    }
}

OffGame으로 이동

detach current child + attach OffGame

  • 부모 Interactor에 OffGame, TicTacToe로 이동하는 기능 선언
// LoggedInInteractor.swift

protocol LoggedInRouting: Routing {
    func routeToOffGame() // < 추가
    func cleanupViews()
}
  • 구현
// LoggedInRouter.swift

    func routeToOffGame() {
        detachCurrentChild()
        attachOffGame()
    }

    private func detachCurrentChild() {
        if let currentChild = currentChild {
            detachChild(currentChild)
            viewController.dismiss(viewController: currentChild.viewControllable)
        }
    }
  • 게임이 끝난 경우에도 OffGame으로 이동
// LoggedInRouter
    func gameDidEnd() {
        router?.routeToOffGame()
    }

TicTacToe 붙이기

TicTacToe Builder 생성 - 이미 되어있는 상태

  • 부모 Router에 TicTacToe Builder 프로퍼티 추가
// LoggedInRouter.swift

private let ticTacToeBuilder: TicTacToeBuildable

    init(interactor: LoggedInInteractable,
         viewController: LoggedInViewControllable,
         offGameBuilder: OffGameBuildable,
         ticTacToeBuilder: TicTacToeBuildable) {
        self.viewController = viewController
        self.offGameBuilder = offGameBuilder
        self.ticTacToeBuilder = ticTacToeBuilder
        super.init(interactor: interactor)
        interactor.router = self
    }
  • Builder에 변경된 Router내용 적용
    func build(withListener listener: LoggedInListener) -> LoggedInRouting {
        let component = LoggedInComponent(dependency: dependency)
        let interactor = LoggedInInteractor()
        interactor.listener = listener

        let offGameBuilder = OffGameBuilder(dependency: component)
        let ticTacToeBuilder = TicTacToeBuilder(dependency: component)
        return LoggedInRouter(
            interactor: interactor,
            viewController: component.LoggedInViewController,
            offGameBuilder: offGameBuilder,
            ticTacToeBuilder: ticTacToeBuilder
        )
    }
  • LoggedInComponent+TicTacToe 생성하여 LoggedinComponent에 TicTacToeComponent속성 구현

detach, attach TicTacToe 

  • TicTacToe로 이동하는 기능 선언
// LoggedInInteractor.swift

protocol LoggedInRouting: Routing {
    func routeToOffGame()
    func routeToTicTacToe() // < 추가
    func cleanupViews()
}
  • 구현
// LoggedInRouter.swift

    func routeToTicTacToe() {
        detachCurrentChild()

        let ticTacToe = ticTacToeBuilder.build(withListener: interactor)
        currentChild = ticTacToe
        attachChild(ticTacToe)
        viewController.present(viewController: ticTacToe.viewControllable)
    }

  • LoggedInInteractable속성에 TicTacToeListener 추가
protocol LoggedInInteractable: Interactable, OffGameListener, TicTacToeListener {
    var router: LoggedInRouting? { get set }
    var listener: LoggedInListener? { get set }
}

게임 종료 시 OffGame으로 이동

// LoggedInteractor.swift

    func gameDidEnd() {
         router?.routeToOffGame()
    }

 

Comments