App coordinators in iOS

Post on 20-Mar-2017

128 views 0 download

Transcript of App coordinators in iOS

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 Coordinatoraka 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 🌞