: ViewController의 역할 중 화면 전환 책임을 가져오는 것을 목표로 한다.
ViewController끼리 서로 알지 못한다.
앱의 메인 흐름을 담당하는 AppCoordinator를 SceneDelegate 아래에 둔다.
앱의 주요 기능이나 흐름의 단위 별로 하위 Coordinator를 만든다.
프로토콜 생성
protocol Coordinator: AnyObject {
var childCoordinators: [Coordinator] { get set }
func start()
}
AppCoordinator 생성
class AppCoordinator: Coordinator {
var navigationController = UINavigationController
var childCoordinators: [Coordinator] = []
init(_ navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
showMainFlow()
}
func showMainFlow() {
let mainCoordinator = MainCoordinator(navigationController)
childCoordinators.append(mainCoordinator)
mainCoordinator.start()
}
SceneDelegate 설정
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var appCoordinator: AppCoordinator?
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
let navigationController = UINavigationController()
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
appCoordinator = AppCoordinator(navigationController)
appCoordinator?.start()
}
}
하위 Coordinator 생성
protocol MainCoordinatorDelegate {
func didSomething()
}
class MainCoordinator: Coordinator {
weak var delegate: MainCoordinatorDelegate?
var navigationController = UINavigationController
var childCoordinators: [Coordinator] = []
var viewController: MainViewController
init(_ navigationController: UINavigationController) {
self.navigationController = navigationController
self.viewController = MainViewController()
}
func start() {
viewController.viewModel = MainViewModel(coordinator: self)
navigationController.viewControllers = [viewController]
}
func showMainViewController() {
let mainCoordinator = MainCoordinator(navigationController)
childCoordinators.append(mainCoordinator)
mainCoordinator.start()
}
func doSomething() {
delegate?.didSomething()
}
}
이벤트 발생 시 Coordinator로 전달
class MainViewModel {
weak var coordinator: MainCoordinator?
...
func buttonTapped() {
coordinator?.doSomething()
}
}
AppCoordinator와 MainCoordinator 연결
class AppCoordinator: Coordinator {
...
func showMainFlow() {
let mainCoordinator = MainCoordinator(navigationController)
mainCoordinator.delegate = self
...
}
}
extension AppCoordinator: MainCoordinatorDelegate {
func didSomething() {
showSubFlow()
}
}