iyOmSd/Title: Swift

[Swift] Coordinator Pattern (1/2) - 기본원리

냄수 2020. 5. 17. 02:31
반응형

iOS 아키텍쳐의 종류는 다양해요

MVC, MVP, MVVM, VIPER, RIBs... 등등 많은데

MVC-C, MVVM-C 이러한 표현을 보신적도 있지않나요??

 

여기서 C는 Coordinator를 의미해요

 

Coordinator란??

화면의 흐름을 제어해주는 역할

라우팅

VC관리

이런 단어들이 어울리겟네요

 

 

말이 좀 어렵지만..

위 그림처럼 이런 원리라고 생각하면 쉽게 접근할 수 있어요

VC에 ViewModel를 의존성주입(DI)하듯

VC를 생성하고 필요한 의존성주입을 할 수 있어요

 

 

기존에는 Storyboard에서 VC를 관리하고 이동시켰어요

라우팅관리를 모두 Storyboard에서 했었죠

혹은 ViewController가 담당했죠

 

 

Coordinator를 사용하면

Coordinator가 VC의 이벤트도 담당하고

라우팅기능 처럼

화면에 대한 동작을 처리해요

 

Coordinator를 사용해서

그 로직을 따로 분리시키는 작업을 하는거에요

VC의 책임이 좀 줄어드는것 같죠?

 

이 아키텍쳐를 왜 쓰나요??

화면간 연결을 더 쉽게 관리할 수 있구요

VC를 더 쉽게 재사용할 수 있구요

계층 관리가 용이하죠

VC가 만들어질 때 의존성 주입(DI)를 통해서 사용할 수 있죠

 

 

 

한 번해보면서 이해해볼게요

protocol Coordinator {
    var childCoordinators: [Coordinator] { get set }
    var nav: UINavigationController { get set }
    
    func start()
}

프로토콜을 만들어줘요

기능으로는 자식Coordinator를 가지고있을 배열과

navigation을 담을 변수

시작시 실행될 함수를 가지고있을거에요

 

 

class MainCoordinator: Coordinator {
    var childCoordinators = [Coordinator]()
    var nav: UINavigationController
    
    init(nav: UINavigationController) {
        self.nav = nav
    }
    
    func start() {
        let vc = MainViewController.instantiate(storyboardName: "Main")
        vc.coordinator = self
        nav.pushViewController(vc, animated: false)
    }
    
    func showSecondVC() {
        let vc = SecondViewController.instantiate(storyboardName: "Main")
        vc.coordinator = self
        nav.pushViewController(vc, animated: true)
    }
}

프로토콜을 채택해서 클래스를 만들어주고

 

start()함수를 정의해줫어요

start를 호출하면 해당하는 VC가 Navigation에 쌓이겟네요

showSecondVC()함수는 두번째화면이 보여지도록 햇어요

 

따라서 MainCoordinator에서는

start, showSecondVC를 통해서

2개의 VC를 관리하고 있네요

 

 

 

 

다음으로는 이제 앱시작시 설정을 변경할거에요

코디네이터를 사용하기위해서

기존의 실행환경을 바꿀거에요

 

plist의 Main Storyboard를 없애주고

class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    var coordinator: MainCoordinator?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        let nav = UINavigationController()
        coordinator = MainCoordinator(nav: nav)
        coordinator?.start()
        
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = nav
        window?.makeKeyAndVisible()
        
        return true
    }
}

위에서 메인 스토리보드설정을 지우고

실행하면 까맣게 나올거에요

 

현재 window의 초기설정이 안들어가서 그래요

방금 지웟잖아요?!

 

새로 window를 만들어줄거에요

AppDelegate에서

window를 새로만들어주고

rootVC로 코디네이터역할을하는 네비게이션을 넣어줄거에요

그리고

 

makeKeyAndVisible

이건 윈도우를 새로만든경우 화면에 보여주기위해

새로 만들었다면 꼭 호출해야하는 함수에요

 

 

 

 

protocol Storyboarded {
    static func instantiate(storyboardName: String) -> Self
}

extension Storyboarded where Self: UIViewController {
    static func instantiate(storyboardName: String) -> Self {
        let id = String(describing: self)
        let storyboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
        return storyboard.instantiateViewController(withIdentifier: id) as! Self
    }
}

Storyboarded 프로토콜은

스토리보드에 접근해서 자신의 타입이름을 identifier로 가진 뷰컨트롤러를 반환해주는

간편한 함수에요

 

이렇게 타입과 identifier을 같게해줬어요

 

String(describing:)

타입을 문자열로 반환해줘요

 

 

 

class MainViewController: UIViewController, Storyboarded {

    weak var coordinator: MainCoordinator?
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func nextVC(_ sender: Any) {
        coordinator?.showSecondVC()
    }
}

메인VC에서

버튼을 클릭하면 코디네이터의 함수를 실행시킬거에요

저함수는 위에서 두번째화면으로 가도록 정의했잖아요?

 

 

아주 잘 실행 되는걸 볼 수 있을거에요

 

 

 

흐름이 다른경우, 혹은 새로운 Navigation이 필요한경우

코디네이터를 새로 만들어서 관리하는 식인것 같아요

 

 

코디네이터패턴을 이해하기위해

간단하게 구현하는 과정을 작성했어요

부족한점들이 많을거에요

많은 조언 부탁드려요 :)

 

 

기본 동작을 다뤄보는 글은 다음게시물에 있어요

2020/05/22 - [iyOmSd/Title: Swift] - [Swift] Coordinator Pattern (2/2) - 기본동작

 

[Swift] Coordinator Pattern (2/2) - 기본동작

2020/05/17 - [iyOmSd/Title: Swift] - [Swift] Coordinator Pattern (1/2) - 기본원리 [Swift] Coordinator Pattern (1/2) - 기본원리 iOS 아키텍쳐의 종류는 다양해요 MVC, MVP, MVVM, VIPER, RIBs... 등등 많은..

nsios.tistory.com

 

반응형