-
코디네이터 패턴 (feat. 진입점: SceneDelegate에서 관리)Swift 2023. 9. 17. 17:38
스위프트에서 코디네이터(Coordinator)는 앱의 네비게이션 흐름을 관리하고, 뷰 컨트롤러 간의 전환을 조정하는 디자인 패턴입니다.
코디네이터는 MVC(Model-View-Controller) 아키텍처를 보완하고, 뷰 컨트롤러의 역할을 단순화시켜 응용 프로그램의 유지보수성과 테스트 용이성을 향상시킵니다. 코디네이터 패턴은 일반적으로 앱 내에서 여러 화면 간의 전환과 네비게이션 로직을 처리하는데 사용됩니다.
주요 목적: 뷰 컨트롤러가 다른 뷰 컨트롤러로 직접적인 전환을 처리하지 않도록 분리하는 것
이렇게 하면 각각의 뷰 컨트롤러는 자신에게 주어진 역할에만 집중, 코드 재사용성과 유연성도 향상됨
코디네이터 패턴 작동 구조:
1. 코디네이터 클래스 생성: `Coordinator`라는 이름의 클래스를 만듭니다. 이 클래스는 앱 내에서 네비게이션 로직 및 화면 전환을 관리합니다.
2. 코디네이터 메서드 구현: `start()`와 같은 메서드를 구현하여 해당 코디네이터가 시작되었음을 나타냅니다. 이 메서드에서 필요한 초기 설정 및 첫 번째 화면으로의 전환 등을 처리합니다.
3. 자식 코디네이터 생성: 필요한 경우, 하위 코디네이터(sub-coordinator)를 생성하여 다른 부분 영역에 대한 네비게이션 로직을 분리합니다.
4. 화면 전환 처리: `UINavigationController`, `UITabBarController` 등과 같은 시스템 제공 컨테이너 뷰 컨트롤러를 사용하여 화면 전환이 발생하는 경우, 해당 객체들을 사용하여 전환이 이루어지도록 합니다.
5. 종료 및 정리: 필요한 경우, 해당 코디네이터가 종료될 때 리소스 정리 등 마무리 작업을 수행합니다.
코디네이터 패턴은 앱 내에서 복잡한 화면간 이동 등에 대해 담당하는 객체.
가독성, 유지보수성 향상
import UIKit // 첫 번째 화면의 뷰 컨트롤러 class ViewControllerA: UIViewController { var coordinator: Coordinator? // 다음 화면으로 전환하는 액션 @IBAction func nextButtonTapped(_ sender: UIButton) { coordinator?.showViewControllerB() } } // 두 번째 화면의 뷰 컨트롤러 class ViewControllerB: UIViewController { var coordinator: Coordinator? // 이전 화면으로 전환하는 액션 @IBAction func backButtonTapped(_ sender: UIButton) { coordinator?.showViewControllerA() } } // 코디네이터 클래스 class Coordinator { let navigationController: UINavigationController init(navigationController: UINavigationController) { self.navigationController = navigationController } // 첫 번째 화면 표시 및 설정 func start() { let viewControllerA = ViewControllerA() viewControllerA.coordinator = self navigationController.pushViewController(viewControllerA, animated: false) } // 두 번째 화면 표시 및 설정 func showViewControllerB() { let viewControllerB = ViewControllerB() viewControllerB.coordinator = self navigationController.pushViewController(viewControllerB, animated: true) } // 이전 화면으로 돌아가기 func showViewControllerA() { navigationController.popViewController(animated: true) } } // 앱 진입점에서 코디네이터 시작하기 (AppDelegate 등) let navigationController = UINavigationController() let coordinator = Coordinator(navigationController: navigationController) coordinator.start()
// // SceneDelegate.swift // CoordinatorPattern // // Created by Lyla on 2023/09/17. // import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? var appCoordinator: Coordinator? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). //guard let _ = (scene as? UIWindowScene) else { return } guard let windowScene = (scene as? UIWindowScene) else { return } window = UIWindow(windowScene: windowScene) window?.makeKeyAndVisible() let navigationController = UINavigationController() navigationController.view.backgroundColor = .white window?.rootViewController = navigationController appCoordinator = Coordinator(navigationController: navigationController) appCoordinator?.start() } func sceneDidDisconnect(_ scene: UIScene) { // Called as the scene is being released by the system. // This occurs shortly after the scene enters the background, or when its session is discarded. // Release any resources associated with this scene that can be re-created the next time the scene connects. // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). } func sceneDidBecomeActive(_ scene: UIScene) { // Called when the scene has moved from an inactive state to an active state. // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. } func sceneWillResignActive(_ scene: UIScene) { // Called when the scene will move from an active state to an inactive state. // This may occur due to temporary interruptions (ex. an incoming phone call). } func sceneWillEnterForeground(_ scene: UIScene) { // Called as the scene transitions from the background to the foreground. // Use this method to undo the changes made on entering the background. } func sceneDidEnterBackground(_ scene: UIScene) { // Called as the scene transitions from the foreground to the background. // Use this method to save data, release shared resources, and store enough scene-specific state information // to restore the scene back to its current state. } }