Top Banner
Introducing Application coordinator Andrey Panov
37

«Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Apr 14, 2017

Download

Software

Mail.Ru Group
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Introducing Application coordinator

Andrey Panov

Page 2: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Polytechnic University

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

2

Page 3: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

[Team]Main team ProTools team

Avito

ActiAgent

ActiDealer

Services

3

Page 4: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

presentation.start()• navigation flow in the apps

• usual way

• changes…

• coordinators 😍

• new way

• tips&tricks

4

Page 5: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Flow…

5

Page 6: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Auth flow

6

Page 7: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

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

7

Page 8: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

ViewController

Router

Open it!

8

Page 9: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Controller A Controller B Controller C Send

[String:AnyObject]String

[Options]

[String:AnyObject] [String:AnyObject]String

9

Page 10: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 11: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

SignUp&Auth flow (Services)

11

Page 12: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

12

Page 13: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

coordinator.start()

• hard to reuse

• every controller knows about other controllers

• hard to change flow

• hard to test

13

Page 14: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Application Coordinators

14

Page 15: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

–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

Page 16: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Auth flow

16

Page 17: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Controller A Controller B Controller C Send

[String: AnyObject] String

[Options]

Coordinator

String

[String: AnyObject]

17

Page 18: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Consists of…

18

Page 19: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 20: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 21: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Enumenum ItemListActions {

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

21

Page 22: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 23: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 24: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 25: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Switching from one flow to another

25

Page 26: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Items Coordinator

ItemsControllerItemController

ItemDetailController

ItemFlow

Edit CoordinatorEditController

VasController

EditFlow

?

26

Page 27: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 28: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 29: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 30: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

30

Page 31: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

How to integrate in the project?

31

Page 32: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

32

Page 33: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Coordinators in project

33

Page 34: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

34

Page 35: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

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

Page 36: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

Application coordinator project

/AndreyPanov/ApplicationCoordinator

Page 37: «Управление логикой переходов между экранами приложения с помощью координаторов», Андрей Панов, Avito

questions?.ask() 🙏

/panovdev