Swift 디자인패턴 Coodinator Pattern (코디네이터 패턴)
Coordinator 패턴은 화면 전환 및 네비게이션 로직을 분리하여 ViewController의 역할을 단순화하고, 앱의 화면 흐름을 관리하기 위한 아키텍처 패턴.
히스토리
- 2022-07-07: 디자인 패턴 스터디 정리
- 2024-11-29: 포스팅 글 재정리 및 조금 더 실용적인 예제 코드로 변경
Coordinator Pattern
코디네이터 패턴은 일반적으로 아래의 구조로 구성
- Coordinator는 모든 구체적인 Coordinator들이 반드시 구현해야 하는 메서드와 속성을 정의하는 인터페이스
- children과 router를 정의하며, 화면 전환 메서드인 present와 dismiss도 정의
- Concrete Coordinator 대신 Coordinator 인터페이스를 사용하여, 부모 Coordinator와 자식 Coordinator 간의 결합도 낮춤
- 부모 Coordinator는 하나의 children coodinator 프로퍼티를 통해 여러 자식 Coordinator를 관리할 수 있음
- Concrete Router 대신 Router 인터페이스를 사용해, Coordinator와 Router 간의 결합을 줄임
- Concrete Coordinator는 Coordinator 프로토콜을 구현한 객체
- 해당 객체에서 ViewController의 생성 방법 및 push 된 순서를 알고 있음
- Router는 모든 구체적인 Router들이 반드시 구현해야 하는 메서드를 정의하는 인터페이스
- ViewContoller의 present와 dismiss 메서드를 포함
- Concrete Router는 ViewContoller를 present하는건 알지만 구체적인 객체에 대해서는 모름
- Coordinator가 Router에게 어떤 ViewController를 사용할지 알려줌
- Concrete View Controller는 MVC에서 일반적으로 사용되는 UIViewController의 서브클래스.
- 다른 뷰 컨트롤러에 대한 정보를 가지지 않으며 화면 전환이 필요한 경우에 Coordinator에 위임
코드 예제
코디네이터 패턴을 가장 간단하게 사용하는 예제
//
// SceneDelegate.swift
// CoordinatorPattern
//
// Created by Hamlit Jason on 2022/08/18.
//
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var mainCoordinator: MainCoordinator?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.backgroundColor = .systemBackground
let navigationController = UINavigationController()
mainCoordinator = MainCoordinator(navigationController: navigationController)
mainCoordinator?.start()
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
}
}
import UIKit
import SnapKit
protocol Coordinator: AnyObject {
var childCoordinators: [Coordinator] { get set }
var navigationController: UINavigationController { get set }
func start()
}
class MainCoordinator: Coordinator {
var childCoordinators: [Coordinator] = []
var navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let mainViewContoller = MainViewController()
mainViewContoller.coordinator = self
navigationController.pushViewController(mainViewContoller, animated: true)
}
func pushToSecondViewController() {
let secondViewCoordinator = SecondViewCoordinator(navigationController: navigationController)
secondViewCoordinator.parentCoordinator = self
childCoordinators.append(secondViewCoordinator) // 메모리에서 제거되지 않도록
secondViewCoordinator.start()
}
}
class MainViewController: UIViewController {
weak var coordinator: MainCoordinator?
let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
[button].forEach { view.addSubview($0) }
button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
button.setTitle("프레젠트 버튼", for: .normal)
button.backgroundColor = .black
button.snp.makeConstraints {
$0.center.equalToSuperview()
}
}
@objc
func didTapButton(_ sender: UIButton) {
print("\(#function)")
self.coordinator?.pushToSecondViewController()
}
}
class SecondViewCoordinator: Coordinator {
var childCoordinators: [Coordinator] = []
var navigationController: UINavigationController
weak var parentCoordinator: MainCoordinator?
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let secondViewController = SecondViewController()
secondViewController.coordinator = self
navigationController.pushViewController(secondViewController, animated: true)
}
}
class SecondViewController: UIViewController {
weak var coordinator: Coordinator?
override func viewDidLoad() {
super.viewDidLoad()
}
}
'apple > DesignPattern, Architecture' 카테고리의 다른 글
iOS Clean Architecture 실습 (MVVM) (0) | 2022.09.29 |
---|---|
iOS Clean Architecture 정리 (코드 분석) (0) | 2022.09.23 |
Swift 디자인패턴 Command Pattern (복합체 패턴) (1) | 2022.07.05 |
Swift 디자인패턴 Chain-of-Responsibility Pattern (책임 연쇄 패턴) (0) | 2022.07.05 |
Swift 디자인패턴 Composite Pattern (복합체 패턴) (1) | 2022.06.15 |