왕논의 연구실

Coordinator 패턴을 활용한 화면 전환 관리 비교 본문

iOS/Swift

Coordinator 패턴을 활용한 화면 전환 관리 비교

ywangnon 2025. 3. 16. 23:40

iOS 개발에서 화면 전환을 관리하는 방식은 앱의 유지보수성과 확장성에 큰 영향을 미칩니다.
특히 화면 흐름이 복잡해질수록 기존 방식과 Coordinator 패턴의 차이점이 명확해집니다.

이번 글에서는 기존 방식과 Coordinator 패턴의 차이를 비교하며,
Coordinator 패턴이 화면 흐름 변경을 어떻게 더 쉽게 만드는지를 살펴보겠습니다.


1️⃣ 기존 방식의 문제점: 모든 화면에서 직접 pushViewController 호출

일반적으로 iOS 앱에서는 pushViewController를 사용해 다음 화면으로 이동합니다.
이 방법은 처음에는 간단해 보이지만, 앱이 커질수록 유지보수가 어려워집니다.

📌 기존 화면 전환 코드 예제 (메모 앱)

class HomeViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(type: .system)
        button.setTitle("새 메모 작성", for: .normal)
        button.addTarget(self, action: #selector(startNewMemo), for: .touchUpInside)
        view.addSubview(button)
    }

    @objc private func startNewMemo() {
        let newMemoVC = NewMemoViewController()
        navigationController?.pushViewController(newMemoVC, animated: true)
    }
}

📌 문제점:

  • HomeViewController에서 NewMemoViewController를 직접 참조하고 있음
  • 만약 새 메모 작성 전에 "태그 추가" 화면을 추가하려면 모든 관련 코드를 수정해야 함

2️⃣ 새로운 화면 추가 시 기존 방식의 문제점

예를 들어, 새 메모 작성 전에 "태그 추가" 화면을 추가해야 하는 상황을 생각해보자.
이 경우 기존 startNewMemo() 함수를 아래처럼 수정해야 한다.

@objc private func startNewMemo() {
    let tagVC = TagSelectionViewController()
    tagVC.onComplete = { [weak self] in
        let newMemoVC = NewMemoViewController()
        self?.navigationController?.pushViewController(newMemoVC, animated: true)
    }
    navigationController?.pushViewController(tagVC, animated: true)
}

📌 문제점:

  • HomeViewController여전히 직접 화면을 관리하고 있음
  • 새로운 화면이 추가될 때마다 모든 관련 코드를 수정해야 함
  • 화면 흐름을 바꿀 때 여러 곳을 수정해야 하기 때문에 유지보수가 어렵다

3️⃣ Coordinator 패턴 적용 후, 화면 흐름 변경

Coordinator 패턴을 사용하면 화면 전환을 별도의 객체(Coordinator)가 담당하기 때문에
화면 이동 로직이 ViewController에서 분리됩니다.

이제 새로운 화면(태그 추가)을 추가해야 하는 경우에도
오직 Coordinator만 수정하면 된다는 것이 가장 큰 장점입니다.


4️⃣ Coordinator 패턴 적용 예제 (메모 앱)

📌 Coordinator 패턴을 활용한 화면 전환

class FeatureCoordinator: Coordinator {
    private let navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }

    func start() {
        navigateToTagSelection()
    }

    private func navigateToTagSelection() {
        let tagVC = TagSelectionViewController()
        tagVC.onComplete = { [weak self] in
            self?.navigateToNewMemo()
        }
        navigationController.pushViewController(tagVC, animated: true)
    }

    private func navigateToNewMemo() {
        let newMemoVC = NewMemoViewController()
        newMemoVC.onComplete = { [weak self] in
            self?.navigateToPreview()
        }
        navigationController.pushViewController(newMemoVC, animated: true)
    }

    private func navigateToPreview() {
        let previewVC = PreviewViewController()
        previewVC.onComplete = { [weak self] in
            self?.navigateToMemoList()
        }
        navigationController.pushViewController(previewVC, animated: true)
    }

    private func navigateToMemoList() {
        navigationController.popToRootViewController(animated: true)
    }
}

📌 개선점:

  • HomeViewController는 화면 이동을 전혀 신경 쓰지 않음
  • 새로운 화면(태그 추가)이 필요하면 오직 Coordinator만 수정하면 됨
  • start() 메서드에서 첫 번째 화면을 TagSelectionViewController로 변경하면 자동으로 적용됨

5️⃣ HomeViewController 코드 비교 (기존 vs Coordinator 적용)

기존 방식 ❌ Coordinator 방식 ✅
HomeViewController에서 직접 pushViewController 호출 HomeViewController는 화면 이동을 모름
새로운 화면을 추가할 때 기존 ViewController 수정 필요 Coordinator만 수정하면 됨
유지보수 어려움 유지보수 쉬움

📌 Coordinator 패턴 적용 후, HomeViewController

class HomeViewController: UIViewController {
    var onStartNewMemo: (() -> Void)?

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(type: .system)
        button.setTitle("새 메모 작성", for: .normal)
        button.addTarget(self, action: #selector(didTapStartNewMemo), for: .touchUpInside)
        view.addSubview(button)
    }

    @objc private func didTapStartNewMemo() {
        onStartNewMemo?()  // Coordinator 화면 전환을 처리함
    }
}

📌 개선점:

  • HomeViewController화면 이동을 직접 처리하지 않음
  • 새로운 화면을 추가할 때도 HomeViewController를 수정할 필요 없음
  • 모든 화면 흐름은 Coordinator가 관리

🎯 Cooperator 패턴 적용 전후 비교 요약

기존 방식 ❌ Coordinator 방식 ✅
pushViewController를 여러 곳에서 직접 호출 화면 이동을 Coordinator가 관리
모든 ViewController가 다음 화면을 알아야 함 ViewController는 이동 로직을 몰라도 됨
새로운 화면 추가 시 모든 관련 코드 수정 필요 Coordinator만 수정하면 됨
유지보수가 어려움 유지보수가 쉬움

🔎 결론: Coordinator 패턴을 사용해야 하는 이유

Coordinator 패턴을 사용하면:

  • 화면 이동을 한 곳에서 관리할 수 있어 코드가 깔끔해짐
  • 기존 화면 코드를 수정하지 않고도 화면 흐름을 바꿀 수 있음
  • 유지보수가 쉬워지고 코드 중복이 줄어듦