2. 뷰 전환은 어디에서 하는가
전글에 이어서 이번에도 뷰 전환은 어디에서 이루어지는가에 대해 알아보겠습니다.
전글에서는 뷰 전화를 View에서 하는 법과 ViewModel에서 하는 법을 알아보았고 이번 글에서는 제 3의 책임자를
두어 화면 전환을 이루는 패턴 Coordinator 패턴에 대해서 알아보겠습니다.
1. Cooridnator의 기본
우선 coordinator의 기본 뼈대 부터 간단하게 보겠습니다.
Coordinator 패턴은 Soroush Khanlou라는 개발자로부터 탄생한 개념입니다.
Khanlou의 글 중에서 이런말이 나옵니다.
Don’t forget, the view controller base class is prefixed with UI. It’s view object, and handling user flow is out of its scope.
: ViewController는 UI를 그리는 것에만 집중하고, 유저 플로우(화면 전환)는 책임의 영역에서 벗어나 있다.
따라서 Khanlou는 이러한 화면 전환을 담당하는 전문 객체를 만들었고 이를 Coordinator혹은 Director라고 말합니다.
Coordinator와 ViewController의 관계는 1:n의 관계입니다.
그리고 Coordinator는 트리처럼 자식 Coordinator를 가지게 됩니다.
그림으로 보자면 다음과 같습니다.
위의 그림에서 통상 MainCoordinator혹은 AppCoordinator, RootCoordinator라는 객체들이 존재 합니다.
이 객체들은 다음과 같이 SceneDelegate에서 선언하게 되며 window의 rootViewController가 되는 UINavigationController혹은 UITabBarController등의 객체를 주입받아 생성되게 됩니다.
여기에서 만약 MainCoordinator가 AuthCoordiantor를 띄우고 싶을경우 다음 함수를 통해서 childCoordinator로 등록을 한후
AuthCoordinator를 시작하면 됩니다.
이렇게 되면 AuthCoordinator에서 데이터 상태에 따라 SignUpController를 띄울지 아니면 LoginViewController를 띄울지
결정 하게 되죠.
여기서 부모 Coordinator가 다음으로 띄울 Coordinator를 childCoordinator로 등록하는 이유는
객체를 계속 유지하기 위해서 입니다.
반대로 AuthCoordinator에서 모든 볼일이 끝나면 MainCoordinator는 AuthCoordinator를 childCoordinator에서 삭제해야합니다.
여기까지 아주 기본적인 Coordinator 패턴에 대한 구성을 살펴 보았습니다.
2. Coordinator 와 View는 어떻게 소통 하는가?
Coordinator가 View의 플로우를 담당하고 있으면 Coordinator와 View간 사이에 소통을 해야합니다.
허나 Coordinator 패턴도 완벽히 정형화 되어있지가 않아서 방법이 한 가지가 아닙니다.
크게 보면 위와 같이 View가 MainCoordinator자체를 주입받아 소통하는 방법과
Coordinator와 View사이를 Delegation 패턴을 이용하여 소통하는 방법이 있습니다.
2-1. Coordinator를 직접 주입 받아서 소통
첫번째 방법은 위에서 처럼 Coordinator를 직접 주입받아서 소통하는 것입니다.
사진에서 처럼 그냥 coordinator를 통하여 원하는 함수를 호출해주면 됩니다.
하지만 제 생각에는 이렇게 할경우 ViewController에서 MainCoordinator의 모든 것에 start(), navigationController, childCoordinator등등 접근할 수 있는 권한이 생겨서 좋지 않는 방법이라고 생각합니다.
Coordinator는 View에다가 꼭 필요한 함수만을 제한적으로 노출 시켜야 한다고 생각합니다.
2-2. Coordinator Protocol을 이용한 소통
제한적으로 원하는 것만 노출 시키려면 Delegation 패턴이 제격이죠.
MainCoordinatorDelegate를 만들어 View와 Coordinator가 소통하게 만드는 것입니다.
이렇게 하는 방법도 나쁘지 않은 방법입니다. 하지만 잘 생각해보시면 한가지 문제점? 불편한점?이 존재하게 됩니다.
이 부분에 대해서는 다음글에서 다루겠습니다.
2-3. ViewController의 Protocol을 이용한 소통
따라서 위의 방식처럼 View가 Coordinator의 protocol을 주입다는 대신에
ViewController의 Protocol을 Coordinator가 채택하여
소통하는 방법을 쓸 수 있습니다.
이런식으로 하면 더 좋은 것이 MainCoordinatorDelegate를 쓸경우 다음과 같이 ViewController들이 속해 있다면
MainCoordinatorDelegate에는 4개의 함수가 생기게 됩니다.
+ showAViewController()
+ showBViewController()
+ showCViewController()
+ showDViewController()
이때 AViewController는 BViewController외에는 연관된 화면이 없다고 가정했을때
위의 4개의 함수 때문에 C,D까지 보여줄 수 있는 수단이 생기게 됩니다. 저는 이러한 상황이 필요가 없는 함수에 접근 권한이
생기게 되니 약간 encapsulate가 잘 되지 않은 것이 아닌가 라는 생각이 듭니다.
하지만 ViewControllerDelegate를 쓸 경우 ViewControllerDelegate에는 다음과 같이 하나의 함수만이 생깁니다.
+ showBViewController()
그리고 AViewController를 갖고 있는 다른 Coordinator도 ViewControllerDelegate만 채택하면 되니 재사용성 또한
더 좋아지지 않을까 생각합니다.
이번글은 Coordinator의 기본적인 구성과 Coordinator와 View간의 화면전환이 이루어지는 법에 대해서 써보았습니다.
다음은 반대로 popViewController()와 childCoordinator의 역할이 끝냈을때 부모 Coordinator가 어떻게 이를
인지하고 childCoordinator를 삭제하는지에 대해 알아보겠습니다.
'iOS' 카테고리의 다른 글
MVVM(5) - Coordinator (0) | 2023.01.05 |
---|---|
MVVM(4) - Coordinator (0) | 2022.12.27 |
MVVM (2) (0) | 2022.12.19 |
MVVM (1) - 바인딩 방법들 (1) | 2022.12.09 |
KeyChain vs UserDefaults(2) (0) | 2022.11.22 |