«Управление логикой переходов между экранами...

Post on 14-Apr-2017

2.649 Views

Category:

Software

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Introducing Application coordinator

Andrey Panov

Polytechnic University

iOS projects: • TopFace • KidBook • VoxClub • ToMesto • SmartMuseum

2

[Team]Main team ProTools team

Avito

ActiAgent

ActiDealer

Services

3

presentation.start()• navigation flow in the apps

• usual way

• changes…

• coordinators 😍

• new way

• tips&tricks

4

Flow…

5

Auth flow

6

didSelectRowAtIndexPath:func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

if 🍌🍌 { router.openControllerA() } else if 🍌🍌🍌 { router.openControllerB() } else if 🍐 { router.openControllerC() } else if 🍐🍐 { router.openControllerD() } }

7

ViewController

Router

Open it!

8

Controller A Controller B Controller C Send

[String:AnyObject]String

[Options]

[String:AnyObject] [String:AnyObject]String

9

prepareForSegue:override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { if segue.identifier == "openControllerA"{ let vc = segue.destinationViewController as! ControllerA vc.monkey = 🐒 } else if segue.identifier == "openControllerB"{ let vc = segue.destinationViewController as! ControllerB vc.tiger = 🐯 } else if segue.identifier == "openControllerC"{ let vc = segue.destinationViewController as! ControllerC vc.frog = 🐸 } else if segue.identifier == "openControllerD"{ let vc = segue.destinationViewController as! ControllerD vc.snake = 🐍 } }

10

SignUp&Auth flow (Services)

11

12

coordinator.start()

• hard to reuse

• every controller knows about other controllers

• hard to change flow

• hard to test

13

Application Coordinators

14

–Soroush Khanlou

«So what is a coordinator? A coordinator is an object that bosses view controllers

around. Taking all of the driving logic out of your view controllers, and moving that stuff one layer up is gonna make your life a

lot more awesome.»

15

Auth flow

16

Controller A Controller B Controller C Send

[String: AnyObject] String

[Options]

Coordinator

String

[String: AnyObject]

17

Consists of…

18

Routerable 🙈protocol Router { weak var presenter:UINavigationController? {get} func present(controller:UIViewController, animated: Bool) func push(controller:UIViewController, animated: Bool) func popController(animated: Bool) func dismissController(animated: Bool) }

extension Router { func present(controller:UIViewController, animated: Bool = true) { presenter?.presentViewController(controller, animated: animated, completion: nil) } func push(controller:UIViewController, animated: Bool = true) { presenter?.pushViewController(controller, animated: animated) } func popController(animated: Bool = true) { presenter?.popViewControllerAnimated(animated) } func dismissController(animated: Bool = true) { presenter?.dismissViewControllerAnimated(true, completion: nil) } }

19

Protocols

protocol Coordinatable: class, Router { var flowCompletionHandler: CoordinatorHandler? {get set} func start() }

protocol FlowController { associatedtype T //enum Actions type var completionHandler: (T -> ())? {get set} }

typealias CoordinatorHandler = () -> ()

20

Enumenum ItemListActions {

case ItemSelect(ItemList) case New case VasSelect(ItemDetail) case Edit(ItemDetail) case VasApply }

21

enum ItemListActions { case ItemSelect(ItemList), Create }

class ItemCoordinator: Coordinatable {

var flowCompletionHandler:CoordinatorHandler? var factory: ItemFactory var coordinatorFactory: CoordinatorFactory private(set) weak var presenter: UINavigationController? var childCoordinators: [Coordinatable] = [] init(presenter: UINavigationController) { self.presenter = presenter factory = ItemFactory() coordinatorFactory = CoordinatorFactory() super.init() } func start() { showItemList() }

22

func showItemList() {

let itemListController = factory.createItemListController() itemListController.completionHandler = { [weak self] result in if case let ItemListActions.ItemSelect(list) = result { self?.showItemDetail(list) } else if case ItemListActions.New = result { self?.runCreationCoordinator() } } push(itemListController) }

ItemCoordinator.swift

23

func showItemList() {

let itemListController = factory.createItemListController() itemListController.completionHandler = { [weak self] result in if case let ItemListActions.ItemSelect(list) = result { self?.showItemDetail(list) } else if case ItemListActions.New = result { self?.runCreationCoordinator() } } push(itemListController, animated: false) }

24

Switching from one flow to another

25

Items Coordinator

ItemsControllerItemController

ItemDetailController

ItemFlow

Edit CoordinatorEditController

VasController

EditFlow

?

26

class CoordinatorFactory { func createAuthCoordinatorTyple() -> (authCoordinator: AuthCoordinator, presenter: UINavigationController) { let presenter = createNavigationController() return (AuthCoordinator(presenter: presenter), presenter) } private func createNavigationController() -> UINavigationController { return UINavigationController.controllerFromStoryboard(.Main) } }

27

func runAuthCoordinator() { let authTuple = coordinatorFactory.createAuthCoordinatorTuple() let authCoordinator = authTuple.authCoordinator authCoordinator.flowCompletionHandler = { [unowned self] in self.dismissController() self.removeDependancy(authCoordinator) //continue the flow… } authCoordinator.start() addDependancy(authCoordinator) present(authTuple.presenter) }

28

AppDelegate.swiftclass AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

private lazy var applicationCoordinator: ApplicationCoordinator = { return ApplicationCoordinator(rootController: self.window!.rootViewController as! UINavigationController)

}()

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { applicationCoordinator.start() return true } }

29

30

How to integrate in the project?

31

32

Coordinators in project

33

34

coordinator.finish()• controllers know nothing about other controllers

• controllers can be easy integrated in different flows

• controllers don’t send data to the others

• easy to reuse

• simplified testing

35

Application coordinator project

/AndreyPanov/ApplicationCoordinator

questions?.ask() 🙏

/panovdev

top related