• Feed
  • Explore
  • Ranking
/
/
    📱 iOS

    [iOS] View 전환 시 강한 결합(Strong Coupling) 문제와 Coordinator 패턴을 활용한 해결 방법

    iosCoordinator Pattern
    지
    지성
    2025.03.12
    ·
    3 min read

    개인 프로젝트에서 한 ViewController에서 다른 ViewController로 이동할 때, 직접 객체를 생성하고 메서드를 호출하는 방식을 사용했다.

    class FirstViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
        }
        
        @IBAction func navigateToNextView(_ sender: UIButton) {
            let secondVC = SecondViewController()
            navigationController?.pushViewController(secondVC, animated: true)
        }
    }

    이 방식에는 여러 문제가 있었다.

    1. ViewController 간의 직접적인 의존성 발생: FirstViewController가 SecondViewController의 구체적인 구현을 알아야 함.

    2. 유지보수 어려움: ViewController 간의 이동 방식이 변경될 경우 모든 호출 코드를 수정해야 함.

    3. 테스트 어려움: FirstViewController가 SecondViewController를 직접 참조하므로, 단위 테스트 작성이 어려워짐.

    검색을 통해 이러한 문제들을 Coordinator 패턴을 도입하여 해결할 수 있었다.


    Coordinator 패턴이란?

    ViewController 간의 이동을 관리하는 별도의 객체(Coordinator)를 두어, ViewController 간 결합도를 낮추는 구조적 패턴

    Coordinator의 핵심 원칙

    • ViewController는 화면 이동을 직접적으로 처리하지 않는다.

    • Coordinator가 화면 전환을 관리하며, ViewController는 Coordinator에게 이동을 요청한다.

    • 화면 이동 로직을 ViewController에서 분리하여 유지보수성을 높인다.

    Coordinator 패턴 적용하기

    Coordinator 프로토콜 정의

    Coordinator는 화면 이동을 담당하는 객체이므로, 이를 추상화한 프로토콜을 정의한다.

    protocol Coordinator {
        func start()
    }

    MainCoordinator 구현

    앱에서 화면 이동을 관리하는 MainCoordinator를 생성하여, ViewController 간의 네비게이션을 담당하도록 한다.

    class MainCoordinator: Coordinator {
        var navigationController: UINavigationController
        
        init(navigationController: UINavigationController) {
            self.navigationController = navigationController
        }
        
        func start() {
            let firstVC = FirstViewController()
            firstVC.coordinator = self
            navigationController.pushViewController(firstVC, animated: false)
        }
        
        func showSecondView() {
            let secondVC = SecondViewController()
            navigationController.pushViewController(secondVC, animated: true)
        }
    }

    ViewController에서 Coordinator 사용하기

    FirstViewController에서 Coordinator를 사용하도록 변경한다.

    class FirstViewController: UIViewController {
        var coordinator: MainCoordinator?
        
        override func viewDidLoad() {
            super.viewDidLoad()
        }
        
        @IBAction func navigateToNextView(_ sender: UIButton) {
            coordinator?.showSecondView()
        }
    }

    AppDelegate 또는 SceneDelegate에서 Coordinator 초기화

    앱이 실행될 때 Coordinator를 초기화하고, UINavigationController에 연결해야 한다.

    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
        var window: UIWindow?
        var coordinator: MainCoordinator?
        
        func scene(
            _ scene: UIScene,
            willConnectTo session: UISceneSession,
            options connectionOptions: UIScene.ConnectionOptions
        ) {
            guard let windowScene = (scene as? UIWindowScene) else { return }
            
            let navController = UINavigationController()
            coordinator = MainCoordinator(navigationController: navController)
            coordinator?.start()
            
            window = UIWindow(windowScene: windowScene)
            window?.rootViewController = navController
            window?.makeKeyAndVisible()
        }
    }






    - 컬렉션 아티클