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의 개념을 모르니 이 코드가 대체 뭔지 이해를 못하겠네요. ㅎㅎ
정리해보도록 하겠습니다.
일단 이 패턴은 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가 필요합니다.
이것이 제가 예시에서 보았던 appDelegate의 AppCoordinator입니다.
모든 Coordinator들은 child coordinator의 배열을 갖습니다.
(특히 탭 바가 있는 앱에선, 각각의 navigation controller가 액션과 플로우를 감독하기 위해 각자의 coordinator를 갖습니다.)
각 coordinator들은 부모 coordinator에 의해 스폰됩니다.
여기까지 봤을 때 Coordinator 패턴의 기본 사용법은
예시는 iOS-Clean-Architecture 프로젝트를 보면서 학습하겠습니다~
Coordinator 패턴을 사용하면서 얻는 이점은 무엇일까요?
ViewController는 이제 Model을 View에 Binding하는 본연의 목표에 집중할 수 있습니다.
Flow 로직이 한 곳에 모여있기 때문에 재사용이 쉽고, 복잡도가 낮아졌습니다.
iOS-Clean-Architecture 프로젝트를 분석해보면서
각각의 목적에 맞게 분리시키는 프로그래밍이 뭔지 점차 알게되가는 것 같습니다.
이해안가던 Coordinator를 학습했으니 다음 예제 분석으로 돌아가보겠습니다!