#2 Beginning MVVM Coordinator - RxSwift MVVM Coordinator iOS App
Coordinator
패턴 사용Coordinator
연결Coordinator
프로토콜 상속import Foundation
protocol Coordinator: AnyObject {
var childCoordinator: [Coordinator] { get set }
func start()
}
extension Coordinator {
func add(coordinator: Coordinator) {
childCoordinator.append(coordinator)
}
func remove(coordinator: Coordinator) {
childCoordinator = childCoordinator.filter({ $0 !== coordinator })
}
}
Coordinator
가 기본으로 상속하는 프로토콜 childCoordinator
는 일종의 싱글턴 패턴 역할start
를 통해 Coordinator
의 기능이 동작import Foundation
class BaseCoordinator: Coordinator {
var childCoordinator: [Coordinator] = []
func start() {
fatalError("Children should be implemented in start func")
}
}
BaseCoordinator
의 childCoordinator
는 동작하지 않지만 이를 상속하는 다른 Coordinator
가 오버라이드해서 사용import UIKit
class SearchCoordinator: BaseCoordinator {
private let navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
override func start() {
let searchVC = SearchViewController()
searchVC.viewModelBuilder = {
SearchViewModel(input: $0)
}
navigationController.pushViewController(searchVC, animated: true)
}
}
SearchCoordinator
에서는 네비게이션 컨트롤러를 신 딜리게이트로부터 건네받아 뷰 컨트롤러를 푸쉬 typealias ViewModelBuilder = (SearchViewPresentable.Input) -> SearchViewPresentable
SearchViewPresentable
은 곧 뷰 모델이 상속하는 프로토콜private
으로 감춰주기 위해 해당 인자를 var
로 노출, 인풋을 주고 해당 SearchViewPresentable
을 건네 받음 private func setViewModel() {
viewModel = viewModelBuilder((
searchText: searchBarController.searchBar.rx.text.orEmpty.asDriver(), ()
))
}
viewDidLoad
함수 단에서 실행viewModelBuilder
클로저를 통해 옵셔널에서 실제 값을 가진 뷰 모델로 전환하는 코드
Driver
가 곧 UI를 그릴 때 사용하기 적합한 Rx 구동자임에 주의하자!Coordinator
패턴에서 네비게이션 컨트롤러까지 넘겨받는 것은 상당히 놀랍다.