ºÝºÝߣ

ºÝºÝߣShare a Scribd company logo
App Coordinators
Overstuffed App Delegate
- (void)setupViewHierarchy {
UITabBarController *tabBarVC = (UITabBarController *)self.window.rootViewController;
if ([AppConfig isPaidApp]) {
[self removeViewControllerOfType:[RRUnlockViewController class]
fromTabBarController:tabBarVC];
}
if ([AppConfig isMeditationApp]) {
if (![AppConfig isPaidApp]) {
[self removeViewControllerOfType:[RRFavoriteViewController class]
fromTabBarController:tabBarVC];
}
RRSoundsViewController *soundsVC = [[UIStoryboard storyboardWithName:@"Sounds" bundle:[NSBundle
mainBundle]] instantiateViewControllerWithIdentifier:@"RRSoundsViewController"];
soundsVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Sounds" image:[UIImage
imageNamed:@"icon_sounds"] tag:1];
soundsVC.meditationManager = self.meditationManager;
UINavigationController *soundsNVC = [[UINavigationController alloc]
initWithRootViewController:soundsVC];
RRTimerViewController *timerVC = [[UIStoryboard storyboardWithName:@"Timer" bundle:[NSBundle
mainBundle]] instantiateViewControllerWithIdentifier:@"RRTimerViewController"];
timerVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Timer" image:[UIImage
imageNamed:@"icon_timer"] tag:1];
timerVC.timerManager = self.timerManager;
UINavigationController *timerNVC = [[UINavigationController alloc]
initWithRootViewController:timerVC];
NSMutableArray *allViewControllers = [tabBarVC.viewControllers mutableCopy];
[allViewControllers insertObject:soundsNVC atIndex:0];
[allViewControllers insertObject:timerNVC atIndex:3];
tabBarVC.viewControllers = allViewControllers;
. . .
Too Many Responsibilities
Model
Domain State & Behavior
View Controller?
?
Mediates Model-View
Interactions
View?
?
Display & Layout
View Controller
Model-View Binding
View Controller
Model-View Binding Subview Allocation
View Controller
Model-View Binding Subview Allocation Data Fetching
View Controller
Model-View Binding Subview Allocation Data Fetching
View Controller
Layout
Model-View Binding Subview Allocation Data Fetching
View Controller
Layout Data Transformation
Model-View Binding Subview Allocation Data Fetching
View Controller
Layout Data Transformation Navigation Flow
Model-View Binding Subview Allocation Data Fetching
View Controller
Layout Data Transformation Navigation Flow
User Input
Model-View Binding Subview Allocation Data Fetching
View Controller
Layout Data Transformation Navigation Flow
User Input Model Mutation
Navigation Flow
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let photo = self.data[indexPath.row]
let nextViewController = PhotosViewController(with: photo)
self.navigationController?.pushViewController(nextViewController)
}
LoginViewController
PhotosViewController
NewPhotoViewController
SavePhotoViewController
Libraries
Frameworks
Libraries
Frameworks
you call
Libraries
Frameworks
you call
call you
App Coordinator
aka Application Controller, Flow Controller
What does a coordinator do?
Model-View Binding Subview Allocation Data Fetching
View Controller
Layout Data Transformation Navigation Flow
User Input Model Mutation
App Coordinator
View Model
Model-View Binding
Subview Allocation
Data Fetching
View Controller
Layout Data Transformation Navigation Flow
User Input Model Mutation
App Coordinator
View Model
Model-View Binding
Subview Allocation
Data Fetching
View Controller
Layout
Data Transformation Navigation Flow
User Input Model Mutation
App Coordinator
View Model
Model-View Binding
Subview Allocation
Data Fetching
View Controller
Layout
Data Transformation
Navigation Flow
User Input Model Mutation
App Coordinator
View Model
Model-View Binding
Subview Allocation
Data Fetching
View Controller
Layout
Data Transformation
Navigation Flow
User Input Model Mutation
App Coordinator
View Model
Model-View Binding
Subview Allocation
Data Fetching
View Controller
Layout
Data Transformation
Navigation Flow
User Input
Model Mutation
App Coordinator
View Model
Model-View Binding
Subview Allocation
Data Fetching
View Controller
Layout
Data Transformation
Navigation Flow
User Input
Model Mutation
App Coordinator
View Model
How to use coordinators?
let dependencies = Dependencies(api: vidmeApi, persistenceManager: realmDB)
appCoordinator = AppCoordinator(window: window!, dependencies: dependencies)
appCoordinator.start()
class AppCoordinator: Coordinator {
private let window: UIWindow
private let dependencies: Dependencies
private var childCoordinators = [Coordinator]()
func start() {
if isLoggedIn {
showContent()
} else {
showAuth()
}
}
}
func showAuth() {
let loginCoordinator = LoginCoordinator(navigationController: self.navigationController,
dependencies: self.dependencies)
loginCoordinator.delegate = self
self.childCoordinators.append(loginCoordinator)
loginCoordinator.start()
}
class LoginCoordinator: Coordinator {
func start() {
let loginViewController = LoginViewController()
loginViewController.api = dependencies.api
loginViewController.persistenceManager = dependencies.persistenceManager
loginViewController.delegate = self
navigationController.pushViewController(loginViewController, animated: true)
}?
?
func loginViewController(viewController: LoginViewController, didLoginUser user: User) {
delegate?.userDidLogin(user)
}
}
Why coordinators are great?
1. View Controllers are isolated
A B C D
A B C D
Coordinator
1. View Controllers are isolated
1. View Controllers are isolated
2. View Controllers are reusable
1. View Controllers are isolated
2. View Controllers are reusable
3. Every task is encapsulated
1. View Controllers are isolated
2. View Controllers are reusable
3. Every task is encapsulated
4. Coordinators are fully in our control
Thanks ?

More Related Content

App coordinators in iOS