Protocol-Oriented MVVM

42
POMVVM @NATASHATHEROBOT

Transcript of Protocol-Oriented MVVM

Page 1: Protocol-Oriented MVVM

POMVVM@NATASHATHEROBOT

Page 2: Protocol-Oriented MVVM
Page 3: Protocol-Oriented MVVM
Page 4: Protocol-Oriented MVVM

"Swift Is a Protocol-Oriented Programming Language"

— Dave Abrahams, Professor of Blowing-Your-Mind

Page 5: Protocol-Oriented MVVM

UITableViewDelegate UITableViewDataSourceUITextFieldDelegateNSURLSessionDelegateCLLocationManagerDelegateMCSessionDelegate

Page 6: Protocol-Oriented MVVM

!

Page 7: Protocol-Oriented MVVM

!

Page 8: Protocol-Oriented MVVM

!

Page 9: Protocol-Oriented MVVM

!

Page 10: Protocol-Oriented MVVM

Artsy Engineering: MVVM in Swift

Page 11: Protocol-Oriented MVVM
Page 12: Protocol-Oriented MVVM

THE PROBLEMclass SwitchWithTextTableViewCell: UITableViewCell {

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

}

Page 13: Protocol-Oriented MVVM

PROTOCOLS TO THE RESCUE !

Page 14: Protocol-Oriented MVVM

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 15: Protocol-Oriented MVVM

extension SwitchWithTextCellProtocol {

var switchColor: UIColor { return .purpleColor() }

}

Page 16: Protocol-Oriented MVVM

class SwitchWithTextTableViewCell: UITableViewCell {

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

}

Page 17: Protocol-Oriented MVVM

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 18: Protocol-Oriented MVVM

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

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

return cell

Page 19: Protocol-Oriented MVVM

!

Page 20: Protocol-Oriented MVVM

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 21: Protocol-Oriented MVVM

// SwitchWithTextTableViewCell

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

Page 22: Protocol-Oriented MVVM

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

Page 23: Protocol-Oriented MVVM

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 24: Protocol-Oriented MVVM

// SettingsViewController

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

Page 25: Protocol-Oriented MVVM

!

Page 26: Protocol-Oriented MVVM

@MHOLLEMANS: MIXINS AND TRAITS IN SWIFT 2.0

Page 27: Protocol-Oriented MVVM
Page 28: Protocol-Oriented MVVM
Page 29: Protocol-Oriented MVVM

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

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

Page 30: Protocol-Oriented MVVM

! "

Page 31: Protocol-Oriented MVVM

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 32: Protocol-Oriented MVVM

protocol ImagePresentable { var imageName: String { get }}

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

func onTextFieldDidEndEditing(textField: UITextField)}

Page 33: Protocol-Oriented MVVM

extension TextPresentable {

var textColor: UIColor { return .blackColor() }

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

Page 34: Protocol-Oriented MVVM

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

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

}

Page 35: Protocol-Oriented MVVM

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

Page 36: Protocol-Oriented MVVM

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 37: Protocol-Oriented MVVM

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

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

Page 38: Protocol-Oriented MVVM

!"#

Page 39: Protocol-Oriented MVVM

"Change is the only constant."— Unknown

Page 40: Protocol-Oriented MVVM

!"

Page 41: Protocol-Oriented MVVM

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

> Use ViewModels to Provide Data for the Protocols

Page 42: Protocol-Oriented MVVM

HOW CAN WE MAKE THIS BETTER?