47
Fly Me to the View Jorge D. Ortiz-Fuentes @jdortiz

201710 Fly Me to the View - iOS Conf SG

Embed Size (px)

Citation preview

Page 1: 201710 Fly Me to the View - iOS Conf SG

Fly Me to the View

Jorge D. Ortiz-Fuentes @jdortiz

Page 2: 201710 Fly Me to the View - iOS Conf SG

A Canonical Examples Production

Page 3: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Agenda★Architecture & Responsibilities

★A modular solution

• Storyboards

• XIBs only

★Benefits

★Recap

Page 4: 201710 Fly Me to the View - iOS Conf SG

Persistance FW

View

Netw

ork

Location FW

Presenter

Entity Gateway

Clean Architecture

Interactor

Entity

Page 5: 201710 Fly Me to the View - iOS Conf SG

Where’s the beef?navigation

Page 6: 201710 Fly Me to the View - iOS Conf SG
Page 7: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Navigation

★Events vs Semantics

★Storyboard vs Decoupled VC

★And without storyboards?

★Dependency Injection

★Memory Management

Page 8: 201710 Fly Me to the View - iOS Conf SG

Responsibilities

Page 9: 201710 Fly Me to the View - iOS Conf SG

MVP

Page 10: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

View

★Known by its beautiful face and its passivity

★Receives the events and passes them to the presenter

★Knows how to navigate

Page 11: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Presenter

★Provides meaning to the user events

★Tells the view what to update

★Knows when and where to navigate

Page 12: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Connector

★Knows the dependencies and how to connect them

★Takes you to the next connector

Page 13: 201710 Fly Me to the View - iOS Conf SG

What about MVVM?

Page 14: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

No worries

★MVP ⇒ Tells

★MVVM ⇒ Notifies

★ Feel free to embrace & extend

Page 15: 201710 Fly Me to the View - iOS Conf SG

A modular solution

Page 16: 201710 Fly Me to the View - iOS Conf SG

Decoupling

Page 17: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

View controller

★Separate event from semantics

★Still, navigation is done here

Page 18: 201710 Fly Me to the View - iOS Conf SG

A new VC

View (VC) Presenter Interactor Entity Gateway

Connector

View (VC) Presenter Interactor Entity Gateway

Connector

1 23

4

Page 19: 201710 Fly Me to the View - iOS Conf SG

Segue from VC

Page 20: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

View Controller: Events

@IBAction func add(_ sender: UIBarButtonItem) { presenter.addButtonTapped()}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { presenter.select(row: indexPath.row)}

Page 21: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Presenter: Navigation Semantics

func addButtonTapped() { view.navigateToAddProgrammer()}

func select(row: Int) { if row < 0 !|| row !>= programmers.count { selectedId = nil } else { let programmer = programmers[row] selectedId = programmer.id view.navigateToProgrammerDetail() }}

Page 22: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

View Controller: Navigation

func navigateToAddProgrammer() { performSegue(withIdentifier: SegueIdentifier.addProgrammer, sender: self)} func navigateToProgrammerDetail() { performSegue(withIdentifier: SegueIdentifier.showProgrammer, sender: self)}

Page 23: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

View Controller: Delegate DI

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { let identifier = try! segueIdentifier(for: segue) switch identifier { case .addProgrammer: connector.prepareAddProgrammer(viewController: segue.destination) case .showProgrammer: connector.prepareProgrammerDetail(viewController: segue.destination, presenter: presenter) }}

Page 24: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Child Connector: Assemble

func assembleModule(view: ProgrammerEditViewController) { let presenter = ProgrammerEditPresenter(otherDep: depencency) view.presenter = presenter view.connector = self presenter.view = view}

Page 25: 201710 Fly Me to the View - iOS Conf SG

#MobAppArch

Implementing navigation and back

★Navigation destination is NOT decided by the view event

★When presented modally, navigation back requires Unwind segue

★ In a navigation controller things happen naturally

Page 26: 201710 Fly Me to the View - iOS Conf SG

Memory Management

Page 27: 201710 Fly Me to the View - iOS Conf SG

Dismiss a VC

View (VC) Presenter Interactor Entity Gateway

Connector

View (VC) Presenter Interactor Entity Gateway

Connector

1 2

Page 28: 201710 Fly Me to the View - iOS Conf SG

Passing parameters

Page 29: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Having the Information

★Perform segue & prepare for segue are disconnected

★ Information for injection:

• Use sender: DON’T

• State in View Controller

• State in Presenter (preferred)

Page 30: 201710 Fly Me to the View - iOS Conf SG

XIBs only

Page 31: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Differences

★Easier to pass the information

★Easier to do the injection: Initializer instead of property

★Presentation is done by the source

★No “big picture” or unwind segues

Page 32: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

VC Injection via Initializer

var presenter: ProgrammerEditPresenter

init(presenter: ProgrammerEditPresenter, nibName: String? = nil, bundle: Bundle? = nil) { self.presenter = presenter super.init(nibName: nil, bundle: nil) presenter.view = self}

Page 33: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Passing Information & Presentation

func navigateToDetail(parameter: String) { let detailViewController = connector.prepareProgrammerDetail(parameter: parameter) navigationController!?.pushViewController(detailViewController, animated: true)}

Page 34: 201710 Fly Me to the View - iOS Conf SG

Benefits

Page 35: 201710 Fly Me to the View - iOS Conf SG

Modify Dependency Injection

Page 36: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Dependencies Change

★Create them in the connector

★Pass them from one connector to the next

Page 37: 201710 Fly Me to the View - iOS Conf SG

Testable

Page 38: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Test Everythingfunc testSegueToAddProgrammerInvokesConnectorToNavigate() { let connectorMock = ProgrammersListConnectorMock(some Dep: DepTestDummy()) sut.connector = connectorMock

sut.performSegue(withIdentifier: ProgrammersTableViewControllerMock.SegueIdentifier.addProgrammer, sender: sut)

XCTAssertEqual(1, connectorMock.prepareAddProgrammerInvoked)}

Page 39: 201710 Fly Me to the View - iOS Conf SG

A/B Testing

Page 40: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Presenter

func addButtonTapped() { if abSelector.isA { view.navigateToAddProgrammerA() } else { view.navigateToAddProgrammerB() }}

Page 41: 201710 Fly Me to the View - iOS Conf SG

#AdvArchMobile

Recap★Navigation is a key part of an advanced

architecture:

• Modular

• Allows passive view

• Not bound to implementation (storyboards)

★Easy to implement & maintain

★Clear benefits

Page 42: 201710 Fly Me to the View - iOS Conf SG

– Anonymous iOS developer

“Fly me to the View Let me play among the Apps”

Page 43: 201710 Fly Me to the View - iOS Conf SG

Thank You!

Page 44: 201710 Fly Me to the View - iOS Conf SG

谢谢

Page 45: 201710 Fly Me to the View - iOS Conf SG

Terima kasih!

Page 46: 201710 Fly Me to the View - iOS Conf SG

ந"#

Page 47: 201710 Fly Me to the View - iOS Conf SG

@jdortiz #AdvArchMobile