Skip to content

[Feat] #11 - Coordinator 및 Factory(VC && Coordinator) 구현#12

Merged
L-j-h-c merged 12 commits intoTeamRecorDream:developfrom
L-j-h-c:feature/#11-Coordinator
Oct 2, 2022
Merged

[Feat] #11 - Coordinator 및 Factory(VC && Coordinator) 구현#12
L-j-h-c merged 12 commits intoTeamRecorDream:developfrom
L-j-h-c:feature/#11-Coordinator

Conversation

@L-j-h-c
Copy link
Copy Markdown
Contributor

@L-j-h-c L-j-h-c commented Sep 30, 2022

👻 작업한 내용

전체적으로 Coordinator / Dependency Container / VC Factory / Coordinator Factory를 구현했습니다.
RD-Navigator 모듈 내에 구현했습니다.

image

Coordinator

CoordinatorBase : 코디네이터가 따르는 protocol 및 최상위 클래스인 BaseCoordinator, 앱의 시작점을 결정해주는 launchInstructor로 구성되어 있습니다.

  • CoordinatorNavigationController : Coordinator에서도 SwipeBack Gesture와 BackButton action을 인지할 수 있도록 하는 클래스입니다.
    • 기본 NaivgationController를 사용하면 backButton을 터치시 Coordinator가 알 수 없습니다. 이를 위해 custom Back Button을 이용합니다.
    • Swipe Back 액션의 경우에서도 CoordinatorNavigationControllerDelegate를 채택하여 코디네이터에 알릴 수 있도록 합니다.
      이 레포를 참고했습니다.
  • Router : 뷰를 Routing(화면전환)하는 클래스입니다.
    • Router를 사용하는 이유, Coordinator는 Flow(화면전환 보다 좀 더 큰 범위)에 대한 것만 관리하고 Router가 화면의 분기를 담당하도록 하여 SRP를 지키도록 합니다. Router를 통해서 Coordinator가 NavigationController에 대해 알 필요가 없어집니다.
    • 또한 custom transition이나 popToRoot와 같은 복잡한 방식의 화면전환을 구현하도록 도와줍니다.
    • 해당 내용은 여기에 잘 나와있습니다.
  • LaunchInstructor : AppCoordinator에서 사용할 진입점을 결정합니다. 추후 소셜로그인과 온보딩이 생긴다면 유효하게 사용할 수 있습니다. Coordinator에서 각 플로우를 진행하다가 app의 상태가 바뀌면(비회원 -> 자동로그인), LaunchInstructor.configure() 메서드를 실행하여 바뀐 상태를 반영합니다.

Coordinators : 실질적으로 화면전환에 사용하는 Coordinator의 구현체들이 존재하는 폴더입니다.

  • 개념
    • 하나의 코디네이터는 여러 뷰컨트롤러를 관리할 수 있습니다.
    • 코디네이터가 추가로 구현되어야 하는 시점은 해당 코디네이터의 시작 화면이 다른 화면으로의 전환 기능을 가지고 있을 때입니다.
      • 코디네이터가 1개만 필요 : 뷰 A에서 버튼 1을 누르면 뷰 B, 버튼 2를 누르면 뷰 C가 모달로 띄워짐
      • 코디네이터가 2개 필요 : 뷰 A에서 버튼 1을 누르면 뷰 B, 버튼 2를 누르면 뷰 C가 모달로 띄워짐. 그런데 뷰 B에서 버튼 3을 누르면 뷰 D가 띄워져야 함. 그렇다면 뷰 B는 새로운 코디네이터를 가져야 함.
  • 현재 유효한 코디네이터 : AppCoordinatorMainTabBarCoordinator입니다.
    • 추후에 구현이 필요한 코디네이터는 MainTabBarCoordinator를 제외하면 AuthCoordinator 정도인 것 같습니다. 이유는 뎁스가 2이상인 플로우가 없기 때문에 MainTabBarCoordinator에서 각 화면으로의 화면전환을 모두 담당할 수 있기 때문입니다.
    • 물론 구현은 하기 나름이지만... 회원 탈퇴 및 로그아웃 시에 로그인 뷰로 이동을 담당하는 분기만 새로운 코디네이터로 해야할 수도 있을 것 같습니다.
  • 실제 사용 예시 : CoordinatorViewModelPublishRelay를 구독하여 이벤트가 들어오면 화면전환을 진행합니다.
    • showHomeViewController()에서 뷰모델의 middleButtonTapped를 구독하고, 이벤트가 들어온 경우 DreamWriteVC를 띄워주고 있습니다.
    • 또한 showDrreamWriteViewController()에서는 viewDidDisappear를 구독하여 화면이 dismiss됨을 코디네이터가 알아차릴 수 있습니다.

image

뷰모델에서는 VC의 action을 구독하여 자신이 가진 middleButtonTapped에 이벤트를 다시 전달하고 있습니다.

image

Factory : 클린 아키텍쳐에서 복잡한 의존성 관리 및 뷰컨트롤러의 생성에 대한 책임을 지니는 클래스입니다.

  • 복잡한 VC 생성 코드를 분리하여 깔끔하게 만들어줍니다.

image

Dependency Container : 각종 인스턴스의 의존성을 보유하는 Container입니다. 이 클래스를 통해서 원할 때 서로 다른 인스턴스 간의 의존성을 관리해줄 수 있습니다.

  • 기능
    • Coordinator를 보유하여 start 메서드를 통해 앱의 플로우를 실행할 수 있습니다.
    • 이외에 다른 Service나 Manager를 보유하여 의존성을 관리합니다.
    • CoordinatorNavigationController를 보유하여 Coordinator에서도 기능하는 NavigationController를 가집니다.
    • 스스로가 Factory로 기능하여 Coordinator가 뷰컨트롤러를 생성할 수 있도록 합니다.
  • 구현
    • Coordinator Factory Protocol을 채택하여 Coordinator를 생성할 수 있도록 구현해야 합니다.
    • ViewController Factory Protocol을 채택하여 ViewController를 생성할 수 있도록 구현해야 합니다.

레퍼런스

https://medium.com/blacklane-engineering/coordinators-essential-tutorial-part-i-376c836e9ba7
https://pavlepesic.medium.com/flow-coordinator-pattern-on-steroids-a52021e31bfe

🎤 PR Point

ViewModel에 따로 Relay를 빼두는게 좋은 방식인지는 모르겠네요..

클린 아키텍쳐를 하기 위해서 생성할 파일들이 많은데 템플릿을 하나 만드는 것도 좋을 것 같습니다.

📮 관련 이슈

@L-j-h-c L-j-h-c added 록시보이 🌽 담당자 feat 구현·개선 사항에 관련된 내용입니다. labels Sep 30, 2022
@L-j-h-c L-j-h-c self-assigned this Sep 30, 2022
@L-j-h-c L-j-h-c merged commit 181da66 into TeamRecorDream:develop Oct 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 구현·개선 사항에 관련된 내용입니다. 록시보이 🌽 담당자

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] Coordinator & (VC, Coordinator) Factory 구현

2 participants