[iOS] Coordinator Pattern

Hyunndy·2023년 2월 5일
0

🐸

iOS Clean Architecture 프로젝트를 분석하다보니 처음보는 개념이 나왔습니다.
FlowCoordinator라는 객체인데요.

final class AppFlowCoordinator {

    var navigationController: UINavigationController
    private let appDIContainer: AppDIContainer
    
    init(navigationController: UINavigationController,
         appDIContainer: AppDIContainer) {
        self.navigationController = navigationController
        self.appDIContainer = appDIContainer
    }

    func start() {
        // In App Flow we can check if user needs to login, if yes we would run login flow
        let moviesSceneDIContainer = appDIContainer.makeMoviesSceneDIContainer()
        let flow = moviesSceneDIContainer.makeMoviesSearchFlowCoordinator(navigationController: navigationController)
        flow.start()
    }
}

이 프로젝트는
테이블뷰 + 서치바가 있는 MovieScene ViewController
셀 클릭 시 나오는 MovieDetail ViewController
두 개의 화면으로 구성되어있는데요.

AppDelegate에서 AppFlowContainer 객체를 생성하고,

        appFlowCoordinator = AppFlowCoordinator(navigationController: navigationController,
                                                appDIContainer: appDIContainer)
        appFlowCoordinator?.start()

객체를 생성한 후에는 메인이 되는 MovieSearch화면의 Dependency 주입 후 MovieSearchFlowCoordinator 객체를 만들어 MovieScene ViewController을 NavigationController에 Push합니다!

    func start() {
        // In App Flow we can check if user needs to login, if yes we would run login flow
        let moviesSceneDIContainer = appDIContainer.makeMoviesSceneDIContainer()
        let flow = moviesSceneDIContainer.makeMoviesSearchFlowCoordinator(navigationController: navigationController)
        flow.start()
    }

Coordinator의 개념을 모르니 이 코드가 대체 뭔지 이해를 못하겠네요. ㅎㅎ
정리해보도록 하겠습니다.


Coordinator 패턴

일단 이 패턴은 iOS-Clean-Architecture 프로젝트를 만든 Soroush Khanlou가 소개한 패턴입니다.
The Coordinator

Khanlou씨는

Big ViewController의 가장 큰 문제 중에 하나는 Flow 로직, View 로직, Business 로직이 얽혀있기 때문이다.

라고 합니다.

예를들면

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  
	id object = [self.dataSource objectAtIndexPath:indexPath];  
	SKDetailViewController *detailViewController = [[SKDetailViewController alloc] initWithDetailObject:object]  
	[self.navigationController presentViewController:detailViewController animated:YES];  
}  

상세 VC를 띄우는 이 코드는 매우 간단하지만, App의 크기가 커질 수록 여러 VC에서 상세 VC를 띄우는 반복코드들이 등장할 것 입니다.

Khanlou씨는

ViewController의 기본 접두사는 UI이며, View 객체 이기 때문에 ViewController가 Flow 로직을 갖고 있는 것은 ViewController의 처리 범위가 아니라고 말합니다.

라고 생각해 한 가지 방법을 제안합니다.

🙋‍♂️ 높은 수준의 객체를 두고, 이 객체가 모든 ViewController를 marshal(특정 목적을 위해서 모으고), manage(관리) 하도록 하자!

이 객체가 바로 Coordinators 또는 Directors 입니다.


Coordinator 사용

이 패턴을 잘 사용하려면 전체 앱을 감독하는 하나의 최상위 레벨 coordinator가 필요합니다.
이것이 제가 예시에서 보았던 appDelegate의 AppCoordinator입니다.

모든 Coordinator들은 child coordinator의 배열을 갖습니다.
(특히 탭 바가 있는 앱에선, 각각의 navigation controller가 액션과 플로우를 감독하기 위해 각자의 coordinator를 갖습니다.)

각 coordinator들은 부모 coordinator에 의해 스폰됩니다.

여기까지 봤을 때 Coordinator 패턴의 기본 사용법은

  • 전체 앱을 감독하는 one-high-level coordinator가 있다.
  • 모든 coordinator는 child coordinator 배열을 갖는다.
  • 각 coordinator는 부모 coordinator에 의해 스폰된다.

예시는 iOS-Clean-Architecture 프로젝트를 보면서 학습하겠습니다~


Coordinator의 이점

Coordinator 패턴을 사용하면서 얻는 이점은 무엇일까요?
ViewController는 이제 Model을 View에 Binding하는 본연의 목표에 집중할 수 있습니다.
Flow 로직이 한 곳에 모여있기 때문에 재사용이 쉽고, 복잡도가 낮아졌습니다.


느낀점

iOS-Clean-Architecture 프로젝트를 분석해보면서
각각의 목적에 맞게 분리시키는 프로그래밍이 뭔지 점차 알게되가는 것 같습니다.
이해안가던 Coordinator를 학습했으니 다음 예제 분석으로 돌아가보겠습니다!

profile
https://hyunndyblog.tistory.com/163 티스토리에서 이사 중

0개의 댓글