Coordinator 패턴은 몇가지 문제점이 있다.
RxFlow는 Coordinator 패턴을 반응형으로 구현한 것이다.
Flow
class WatchedFlow: Flow {
var root: UIViewController {
return self.rootViewController
}
private let rootViewController = UINavigationController()
private let service: MoviesService
init(withService service: MoviesService) {
self.service = service
}
func navigate(to step: Step) -> [NextFlowItem] {
guard let step = step as? DemoStep else { return NextFlowItem.noNavigation }
switch step {
case .movieList:
return navigateToMovieListScreen()
case .moviePicked(let movieId):
return navigateToMovieDetailScreen(with: movieId)
case .castPicked(let castId):
return navigateToCastDetailScreen(with: castId)
default:
return NextFlowItem.noNavigation
}
}
private func navigateToMovieListScreen () -> [NextFlowItem] {
let viewModel = WatchedViewModel(with: self.service)
let viewController = WatchedViewController.instantiate(with: viewModel)
viewController.title = "Watched"
self.rootViewController.pushViewController(viewController, animated: true)
return [NextFlowItem(nextPresentable: viewController, nextStepper: viewModel)]
}
private func navigateToMovieDetailScreen (with movieId: Int) -> [NextFlowItem] {
let viewModel = MovieDetailViewModel(withService: self.service,
andMovieId: movieId)
let viewController = MovieDetailViewController.instantiate(with: viewModel)
viewController.title = viewModel.title
self.rootViewController.pushViewController(viewController, animated: true)
return [NextFlowItem(nextPresentable: viewController, nextStepper: viewModel)]
}
private func navigateToCastDetailScreen (with castId: Int) -> [NextFlowItem] {
let viewModel = CastDetailViewModel(withService: self.service,
andCastId: castId)
let viewController = CastDetailViewController.instantiate(with: viewModel)
viewController.title = viewModel.name
self.rootViewController.pushViewController(viewController, animated: true)
return NextFlowItem.noNavigation
}
}
Step
enum DemoStep: Step {
// Global
case logoutIsRequired
case dashboardIsRequired
case alert(String)
case fakeStep
case unauthorized
// Login
case loginIsRequired
case userIsLoggedIn
// Api Key
case apiKeyIsRequired
case apiKeyIsFilledIn
// Onboarding
case onboardingIsRequired
case onboardingIsComplete
// Movies
case moviesAreRequired
case movieIsPicked (withId: Int)
case castIsPicked (withId: Int)
// Settings
case settingsAreRequired
case settingsAreComplete
// About
case aboutIsRequired
case aboutIsComplete
// Trending
case trendingsAreRequired
// Cast List
case castListAreRequired
}
Stepper
Presentable
Flowable
Coordinator
navigate(to:)
함수navigate(to:)
함수가 Step을 FlowContributors로 변형한다.