Protocol-Oriented MVVM (extended edition)

55
POMVVM @NATASHATHEROBOT

Transcript of Protocol-Oriented MVVM (extended edition)

Page 1: Protocol-Oriented MVVM (extended edition)

POMVVM@NATASHATHEROBOT

Page 2: Protocol-Oriented MVVM (extended edition)
Page 3: Protocol-Oriented MVVM (extended edition)
Page 4: Protocol-Oriented MVVM (extended edition)

"Swift Is a Protocol-Oriented Programming Language"

— Dave Abrahams, Professor of Blowing-Your-Mind

Page 5: Protocol-Oriented MVVM (extended edition)

UITableViewDelegate UITableViewDataSourceUITextFieldDelegateNSURLSessionDelegateCLLocationManagerDelegateMCSessionDelegate

Page 6: Protocol-Oriented MVVM (extended edition)

!

Page 7: Protocol-Oriented MVVM (extended edition)

!

Page 8: Protocol-Oriented MVVM (extended edition)

!

Page 9: Protocol-Oriented MVVM (extended edition)

!

Page 10: Protocol-Oriented MVVM (extended edition)

Artsy Engineering: MVVM in Swift

Page 11: Protocol-Oriented MVVM (extended edition)

MODELlet amount = 6729383.99

Page 12: Protocol-Oriented MVVM (extended edition)

VIEWYour balance is $6,729,383.99

Page 13: Protocol-Oriented MVVM (extended edition)

VIEWMODELstruct AccountViewModel { let displayBalance: String

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

Page 14: Protocol-Oriented MVVM (extended edition)

VIEWCONTROLLERvar viewModel = ViewModel(model: Account)

Page 15: Protocol-Oriented MVVM (extended edition)
Page 16: Protocol-Oriented MVVM (extended edition)
Page 17: Protocol-Oriented MVVM (extended edition)
Page 18: Protocol-Oriented MVVM (extended edition)

VIEWCONTROLLERvar viewModel = ViewModel(model: Account)

Page 19: Protocol-Oriented MVVM (extended edition)

PROTOCOLS!!!

Page 20: Protocol-Oriented MVVM (extended edition)
Page 21: Protocol-Oriented MVVM (extended edition)

THE PROBLEMclass SwitchWithTextTableViewCell: UITableViewCell {

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

}

Page 22: Protocol-Oriented MVVM (extended edition)

PROTOCOLS TO THE RESCUE !

Page 23: Protocol-Oriented MVVM (extended edition)

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)}

Page 24: Protocol-Oriented MVVM (extended edition)

extension SwitchWithTextCellProtocol {

var switchColor: UIColor { return .purpleColor() }

}

Page 25: Protocol-Oriented MVVM (extended edition)

class SwitchWithTextTableViewCell: UITableViewCell {

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

}

Page 26: Protocol-Oriented MVVM (extended edition)

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!") } }}

Page 27: Protocol-Oriented MVVM (extended edition)

CELLFORROWATINDEXPATH// YourViewController.swiftlet cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell

// this is where the magic happens!cell.configure(withDelegate: MinionModeViewModel())

return cell

Page 28: Protocol-Oriented MVVM (extended edition)

!

Page 29: Protocol-Oriented MVVM (extended edition)

Page 30: Protocol-Oriented MVVM (extended edition)

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 }}

Page 31: Protocol-Oriented MVVM (extended edition)

// SwitchWithTextTableViewCell

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

Page 32: Protocol-Oriented MVVM (extended edition)

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

Page 33: Protocol-Oriented MVVM (extended edition)

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!") } }}

Page 34: Protocol-Oriented MVVM (extended edition)

// SettingsViewController

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

Page 35: Protocol-Oriented MVVM (extended edition)

!

Page 36: Protocol-Oriented MVVM (extended edition)

@MHOLLEMANS: MIXINS AND TRAITS IN SWIFT 2.0

Page 37: Protocol-Oriented MVVM (extended edition)
Page 38: Protocol-Oriented MVVM (extended edition)
Page 39: Protocol-Oriented MVVM (extended edition)

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

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

Page 40: Protocol-Oriented MVVM (extended edition)

! "

Page 41: Protocol-Oriented MVVM (extended edition)

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)}

Page 42: Protocol-Oriented MVVM (extended edition)

protocol ImagePresentable { var imageName: String { get }}

protocol TextFieldPresentable { var placeholder: String { get } var text: String { get }

func onTextFieldDidEndEditing(textField: UITextField)}

Page 43: Protocol-Oriented MVVM (extended edition)

extension TextPresentable {

var textColor: UIColor { return .blackColor() }

var font: UIFont { return .systemFontOfSize(17) }}

Page 44: Protocol-Oriented MVVM (extended edition)

!!!class SwitchWithTextTableViewCell<T where T: TextPresentable, T: SwitchPresentable>: UITableViewCell { private var delegate: T?

func configure(withDelegate delegate: T) { // configure views here }

}

Page 45: Protocol-Oriented MVVM (extended edition)

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

Page 46: Protocol-Oriented MVVM (extended edition)

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!") } }}

Page 47: Protocol-Oriented MVVM (extended edition)

let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell<MinionModeViewModel>

let viewModel = MinionModeViewModel()cell.configure(withDelegate: viewModel)return cell

Page 48: Protocol-Oriented MVVM (extended edition)

!"#

Page 49: Protocol-Oriented MVVM (extended edition)

"Change is the only constant."— Unknown

Page 50: Protocol-Oriented MVVM (extended edition)
Page 51: Protocol-Oriented MVVM (extended edition)

class SwitchWithTextTableViewCell<T where T: TextPresentable, T: SwitchPresentable, T: ImagePresentable>: UITableViewCell {

}

Page 52: Protocol-Oriented MVVM (extended edition)

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

Page 53: Protocol-Oriented MVVM (extended edition)

!"

Page 54: Protocol-Oriented MVVM (extended edition)

> Use Protocols to Configure Your Views> Use Protocol Extensions for Defaults

> Use ViewModels to Provide Data for the Protocols

Page 55: Protocol-Oriented MVVM (extended edition)

HOW CAN WE MAKE THIS BETTER?