-
Notifications
You must be signed in to change notification settings - Fork 0
Coordinator
Jinwon Choi edited this page Mar 19, 2025
·
1 revision
ViewController 이용한 화면 전환에서 발생하는 여러 문제들을 줄이기 위한 방법
- ViewController에서 pop, push 등을 이용한 화면 전환까지 담당하는 많은 책임을 가지고 있다.
- 커진 VC에서 화면 전환 로직만을 찾아 확인하고 수정하기 번거롭다.
- VC에서 처리하면서 결합도가 너무 높다.
- 화면 전환을 위한 VC마다 새롭게 인스턴스를 생성해야 전환시킬 수 있다.
화면 전환 로직을 관리하는 Coordinator 객체를 만들어 ViewController가 아닌 Coordinator가 해당 역할을 수행하도록 하는 구조이다. Coordinator는 앱의 주요 흐름을 컨트롤하며, 각 부분에 따라 여러 Coordinator가 존재할 수 있다.

- 단일 책임 원칙
- 화면 전환 역할을 하는 객체인 Coordinator의 존재로, VC은 UI에만 집중할 수 있어진다.
- 재사용성
- Coordinator는 특정 플로우데 따라 여러개가 있을 수 있는데, 동일한 플로우가 필요하다면 여러 곳에서 재사용 가능하다.
- 화면 전환 로직 변경
- Coordinator에서 화면 전환과 네비게이션을 관리하기 때문에 로직 수정이 더 간단하다.
- 순환 참조
- Coordinator의 개수가 많아질수록 순환 참조의 위험성이 발생한다.
- 배열에 Coordinator를 저장하고, 필요 없는 경우 해제하는 방식으로 방지할 수 있다.
- 확장성
- 복잡한 화면 전환 플로우를 가진 대규모 앱일수록 적합하다.
- Coordinator 프로토콜
- 모든 코디네이터는 공통된 메서드를 따르기 위해서 코디네이터 프로토콜을 채택한다.
- App Coordinator
- 앱의 공통 네비게이션 기능을 제공하며, 주로 자식 코디네이터를 관리하거나 현재 상태를 유지한다.
- 각각의 Coordinator
- 특정 흐름을 담당하는 코디네이터(위에서 말한 자식 코드네이터)로, 각각의 흐름을 관리하고 VC과의 네비게이션을 수행한다.
- Delegate 패턴 / Closure
- 상위 코디네이터와 하위 코디네이터가 서로 상호작용할때 주로 델리게이트나 클로저로 상호작용한다.
- 델리게이트와 클로저로 상호작용 하기 때문에 코디네이터를 독립적인 모듈로 유지할 수 있다.
- 기본 화면 전환

-
Coordinator 화면 전환
Coordinator 자체가 화면 전환 객체이기 때문에, 화면끼리의 전환 로직이 필요한 것이 아니라 Coordinator와 연결되어 화면 전환을 요청하기만 하면 된다.

- Coordinator 프로토콜
protocol Coordinator {
var childCoordinators: [Coordinator] { get set }
var navigationController: UINavigationController { get set }
func start()
}- childCoordinators : 하위 Coordinator 가 들어갈 배열
- navigationController : 자신 ViewController들을 보여줄 역할
- start() : 해당 Coordinator가 관리하는 화면 표시하는 메서드
- AppCoordinator - 코디네이터의 최상위
class AppCoordinator: Coordinator {
var childCoordinators = [Coordinator]()
var navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let authCoordinator = AuthCoordinator(navigationController: navigationController)
authCoordinator.parentCoordinator = self
childCoordinators.append(authCoordinator)
authCoordinator.start()
}
func didFinishAuth() {
// 회원가입 끝났으니 로그인 화면으로 넘어가기
let loginCoordinator = LoginCoordinator(navigationController: navigationController)
childCoordinators.append(loginCoordinator)
loginCoordinator.start()
}
}- AuthCoordinator
class AuthCoordinator: Coordinator {
var childCoordinators = [Coordinator]()
var navigationController: UINavigationController
weak var parentCoordinator: AppCoordinator?
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let authViewController = AuthViewController()
authViewController.coordinator = self
navigationController.pushViewController(authViewController, animated: true)
}
func didFinishAuth() {
parentCoordinator?.didFinishAuth()
}
}- AuthViewController
class AuthViewController: UIViewController {
weak var coordinator: AuthCoordinator?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
// 회원가입 UI 설정
}
func authSuccessButtonTapped() {
// 회원가입 로직
coordinator?.didFinishLogin()
}
}https://velog.io/@kimscastle/iOS-Coordinator-Pattern-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0
NI, MPC
리팩토링/리디자인
테스트
Supabase
- 배현진
- 윤지성
- 최진원
- 허혜민