Slide 1

Slide 1 text

POMVVM @NATASHATHEROBOT

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

"Swift Is a Protocol-Oriented Programming Language" — Dave Abrahams, Professor of Blowing-Your-Mind

Slide 5

Slide 5 text

UITableViewDelegate UITableViewDataSource UITextFieldDelegate NSURLSessionDelegate CLLocationManagerDelegate MCSessionDelegate

Slide 6

Slide 6 text

!

Slide 7

Slide 7 text

!

Slide 8

Slide 8 text

!

Slide 9

Slide 9 text

!

Slide 10

Slide 10 text

Artsy Engineering: MVVM in Swift

Slide 11

Slide 11 text

MODEL let amount = 6729383.99

Slide 12

Slide 12 text

VIEW Your balance is $6,729,383.99

Slide 13

Slide 13 text

VIEWMODEL struct AccountViewModel { let displayBalance: String init(model: BankAccount) { let formattedBalance = model.balance.currencyValue displayBalance = "Your balance is \(formattedBalance)" } }

Slide 14

Slide 14 text

VIEWCONTROLLER var viewModel = ViewModel(model: Account)

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

VIEWCONTROLLER var viewModel = ViewModel(model: Account)

Slide 19

Slide 19 text

PROTOCOLS !!!

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

THE PROBLEM class SwitchWithTextTableViewCell: UITableViewCell { func configure( title: String, titleFont: UIFont, titleColor: UIColor, switchOn: Bool, switchColor: UIColor = .purpleColor(), onSwitchToggleHandler: onSwitchToggleHandlerType? = nil) { // configure views here } }

Slide 22

Slide 22 text

PROTOCOLS TO THE RESCUE !

Slide 23

Slide 23 text

protocol SwitchWithTextCellProtocol { var title: String { get } var titleFont: UIFont { get } var titleColor: UIColor { get } var switchOn: Bool { get } var switchColor: UIColor { get } func onSwitchTogleOn(on: Bool) }

Slide 24

Slide 24 text

extension SwitchWithTextCellProtocol { var switchColor: UIColor { return .purpleColor() } }

Slide 25

Slide 25 text

class SwitchWithTextTableViewCell: UITableViewCell { func configure(withDelegate delegate: SwitchWithTextCellProtocol) { // configure views here } }

Slide 26

Slide 26 text

struct MinionModeViewModel: SwitchWithTextCellProtocol { var title = "Minion Mode!!!" var switchOn = true var switchColor: UIColor { return .yellowColor() } func onSwitchTogleOn(on: Bool) { if on { print("The Minions are here to stay!") } else { print("The Minions went out to play!") } } }

Slide 27

Slide 27 text

CELLFORROWATINDEXPATH // YourViewController.swift let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell // this is where the magic happens! cell.configure(withDelegate: MinionModeViewModel()) return cell

Slide 28

Slide 28 text

!

Slide 29

Slide 29 text

Slide 30

Slide 30 text

protocol SwitchWithTextCellDataSource { var title: String { get } var switchOn: Bool { get } } protocol SwitchWithTextCellDelegate { func onSwitchTogleOn(on: Bool) var switchColor: UIColor { get } var textColor: UIColor { get } var font: UIFont { get } }

Slide 31

Slide 31 text

// SwitchWithTextTableViewCell func configure(withDataSource dataSource: SwitchWithTextCellDataSource, delegate: SwitchWithTextCellDelegate?) { // configure views here }

Slide 32

Slide 32 text

struct MinionModeViewModel: SwitchWithTextCellDataSource { var title = "Minion Mode!!!" var switchOn = true }

Slide 33

Slide 33 text

extension MinionModeViewModel: SwitchWithTextCellDelegate { var switchColor: UIColor { return .yellowColor() } func onSwitchTogleOn(on: Bool) { if on { print("The Minions are here to stay!") } else { print("The Minions went out to play!") } } }

Slide 34

Slide 34 text

// SettingsViewController let viewModel = MinionModeViewModel() cell.configure(withDataSource: viewModel, delegate: viewModel) return cell

Slide 35

Slide 35 text

!

Slide 36

Slide 36 text

@MHOLLEMANS: MIXINS AND TRAITS IN SWIFT 2.0

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

class AIPlayer: GameObject, AITrait, GunTrait, RenderTrait, HealthTrait { ... } class ZapMonster: GameObject, GunTrait, RenderTrait, HealthTrait, MovementTrait { ... }

Slide 40

Slide 40 text

! "

Slide 41

Slide 41 text

protocol TextPresentable { var text: String { get } var textColor: UIColor { get } var font: UIFont { get } } protocol SwitchPresentable { var switchOn: Bool { get } var switchColor: UIColor { get } func onSwitchTogleOn(on: Bool) }

Slide 42

Slide 42 text

protocol ImagePresentable { var imageName: String { get } } protocol TextFieldPresentable { var placeholder: String { get } var text: String { get } func onTextFieldDidEndEditing(textField: UITextField) }

Slide 43

Slide 43 text

extension TextPresentable { var textColor: UIColor { return .blackColor() } var font: UIFont { return .systemFontOfSize(17) } }

Slide 44

Slide 44 text

!!! class SwitchWithTextTableViewCell: UITableViewCell { private var delegate: T? func configure(withDelegate delegate: T) { // configure views here } }

Slide 45

Slide 45 text

extension MinionModeViewModel: TextPresentable { var text: String { return "Minion Mode" } var textColor: UIColor { return .blackColor() } var font: UIFont { return .systemFontOfSize(17.0) } }

Slide 46

Slide 46 text

extension MinionModeViewModel: SwitchPresentable { var switchOn: Bool { return false } var switchColor: UIColor { return .yellowColor() } func onSwitchTogleOn(on: Bool) { if on { print("The Minions are here to stay!") } else { print("The Minions went out to play!") } } }

Slide 47

Slide 47 text

let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell let viewModel = MinionModeViewModel() cell.configure(withDelegate: viewModel) return cell

Slide 48

Slide 48 text

!"#

Slide 49

Slide 49 text

"Change is the only constant." — Unknown

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

class SwitchWithTextTableViewCell: UITableViewCell { }

Slide 52

Slide 52 text

extension MinionModeViewModel: ImagePresentable { var imageName: String { return "minionParty.png" } }

Slide 53

Slide 53 text

!"

Slide 54

Slide 54 text

> Use Protocols to Configure Your Views > Use Protocol Extensions for Defaults > Use ViewModels to Provide Data for the Protocols

Slide 55

Slide 55 text

HOW CAN WE MAKE THIS BETTER?