Successfully reported this slideshow.

Protocol-Oriented MVVM (extended edition)

11

Share

Loading in …3
×
1 of 55
1 of 55

Protocol-Oriented MVVM (extended edition)

11

Share

Download to read offline

Description

Originally presented at do {iOS} http://do-ios.com/#!/home#speakers

Transcript

  1. 1. POMVVM@NATASHATHEROBOT
  2. 2. "Swift Is a Protocol-Oriented Programming Language" — Dave Abrahams, Professor of Blowing-Your-Mind
  3. 3. UITableViewDelegate UITableViewDataSource UITextFieldDelegate NSURLSessionDelegate CLLocationManagerDelegate MCSessionDelegate
  4. 4. !
  5. 5. !
  6. 6. !
  7. 7. !
  8. 8. Artsy Engineering: MVVM in Swift
  9. 9. MODEL let amount = 6729383.99
  10. 10. VIEW Your balance is $6,729,383.99
  11. 11. VIEWMODEL struct AccountViewModel { let displayBalance: String init(model: BankAccount) { let formattedBalance = model.balance.currencyValue displayBalance = "Your balance is (formattedBalance)" } }
  12. 12. VIEWCONTROLLER var viewModel = ViewModel(model: Account)
  13. 13. VIEWCONTROLLER var viewModel = ViewModel(model: Account)
  14. 14. PROTOCOLS !!!
  15. 15. THE PROBLEM class SwitchWithTextTableViewCell: UITableViewCell { func configure( title: String, titleFont: UIFont, titleColor: UIColor, switchOn: Bool, switchColor: UIColor = .purpleColor(), onSwitchToggleHandler: onSwitchToggleHandlerType? = nil) { // configure views here } }
  16. 16. PROTOCOLS TO THE RESCUE !
  17. 17. 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) }
  18. 18. extension SwitchWithTextCellProtocol { var switchColor: UIColor { return .purpleColor() } }
  19. 19. class SwitchWithTextTableViewCell: UITableViewCell { func configure(withDelegate delegate: SwitchWithTextCellProtocol) { // configure views here } }
  20. 20. 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!") } } }
  21. 21. CELLFORROWATINDEXPATH // YourViewController.swift let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell // this is where the magic happens! cell.configure(withDelegate: MinionModeViewModel()) return cell
  22. 22. !
  23. 23.
  24. 24. 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 } }
  25. 25. // SwitchWithTextTableViewCell func configure(withDataSource dataSource: SwitchWithTextCellDataSource, delegate: SwitchWithTextCellDelegate?) { // configure views here }
  26. 26. struct MinionModeViewModel: SwitchWithTextCellDataSource { var title = "Minion Mode!!!" var switchOn = true }
  27. 27. 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!") } } }
  28. 28. // SettingsViewController let viewModel = MinionModeViewModel() cell.configure(withDataSource: viewModel, delegate: viewModel) return cell
  29. 29. !
  30. 30. @MHOLLEMANS: MIXINS AND TRAITS IN SWIFT 2.0
  31. 31. class AIPlayer: GameObject, AITrait, GunTrait, RenderTrait, HealthTrait { ... } class ZapMonster: GameObject, GunTrait, RenderTrait, HealthTrait, MovementTrait { ... }
  32. 32. ! "
  33. 33. 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) }
  34. 34. protocol ImagePresentable { var imageName: String { get } } protocol TextFieldPresentable { var placeholder: String { get } var text: String { get } func onTextFieldDidEndEditing(textField: UITextField) }
  35. 35. extension TextPresentable { var textColor: UIColor { return .blackColor() } var font: UIFont { return .systemFontOfSize(17) } }
  36. 36. !!! class SwitchWithTextTableViewCell<T where T: TextPresentable, T: SwitchPresentable>: UITableViewCell { private var delegate: T? func configure(withDelegate delegate: T) { // configure views here } }
  37. 37. extension MinionModeViewModel: TextPresentable { var text: String { return "Minion Mode" } var textColor: UIColor { return .blackColor() } var font: UIFont { return .systemFontOfSize(17.0) } }
  38. 38. 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!") } } }
  39. 39. let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell<MinionModeViewModel> let viewModel = MinionModeViewModel() cell.configure(withDelegate: viewModel) return cell
  40. 40. !"#
  41. 41. "Change is the only constant." — Unknown
  42. 42. class SwitchWithTextTableViewCell<T where T: TextPresentable, T: SwitchPresentable, T: ImagePresentable>: UITableViewCell { }
  43. 43. extension MinionModeViewModel: ImagePresentable { var imageName: String { return "minionParty.png" } }
  44. 44. !"
  45. 45. > Use Protocols to Configure Your Views > Use Protocol Extensions for Defaults > Use ViewModels to Provide Data for the Protocols
  46. 46. HOW CAN WE MAKE THIS BETTER?

Description

Originally presented at do {iOS} http://do-ios.com/#!/home#speakers

Transcript

  1. 1. POMVVM@NATASHATHEROBOT
  2. 2. "Swift Is a Protocol-Oriented Programming Language" — Dave Abrahams, Professor of Blowing-Your-Mind
  3. 3. UITableViewDelegate UITableViewDataSource UITextFieldDelegate NSURLSessionDelegate CLLocationManagerDelegate MCSessionDelegate
  4. 4. !
  5. 5. !
  6. 6. !
  7. 7. !
  8. 8. Artsy Engineering: MVVM in Swift
  9. 9. MODEL let amount = 6729383.99
  10. 10. VIEW Your balance is $6,729,383.99
  11. 11. VIEWMODEL struct AccountViewModel { let displayBalance: String init(model: BankAccount) { let formattedBalance = model.balance.currencyValue displayBalance = "Your balance is (formattedBalance)" } }
  12. 12. VIEWCONTROLLER var viewModel = ViewModel(model: Account)
  13. 13. VIEWCONTROLLER var viewModel = ViewModel(model: Account)
  14. 14. PROTOCOLS !!!
  15. 15. THE PROBLEM class SwitchWithTextTableViewCell: UITableViewCell { func configure( title: String, titleFont: UIFont, titleColor: UIColor, switchOn: Bool, switchColor: UIColor = .purpleColor(), onSwitchToggleHandler: onSwitchToggleHandlerType? = nil) { // configure views here } }
  16. 16. PROTOCOLS TO THE RESCUE !
  17. 17. 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) }
  18. 18. extension SwitchWithTextCellProtocol { var switchColor: UIColor { return .purpleColor() } }
  19. 19. class SwitchWithTextTableViewCell: UITableViewCell { func configure(withDelegate delegate: SwitchWithTextCellProtocol) { // configure views here } }
  20. 20. 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!") } } }
  21. 21. CELLFORROWATINDEXPATH // YourViewController.swift let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell // this is where the magic happens! cell.configure(withDelegate: MinionModeViewModel()) return cell
  22. 22. !
  23. 23.
  24. 24. 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 } }
  25. 25. // SwitchWithTextTableViewCell func configure(withDataSource dataSource: SwitchWithTextCellDataSource, delegate: SwitchWithTextCellDelegate?) { // configure views here }
  26. 26. struct MinionModeViewModel: SwitchWithTextCellDataSource { var title = "Minion Mode!!!" var switchOn = true }
  27. 27. 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!") } } }
  28. 28. // SettingsViewController let viewModel = MinionModeViewModel() cell.configure(withDataSource: viewModel, delegate: viewModel) return cell
  29. 29. !
  30. 30. @MHOLLEMANS: MIXINS AND TRAITS IN SWIFT 2.0
  31. 31. class AIPlayer: GameObject, AITrait, GunTrait, RenderTrait, HealthTrait { ... } class ZapMonster: GameObject, GunTrait, RenderTrait, HealthTrait, MovementTrait { ... }
  32. 32. ! "
  33. 33. 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) }
  34. 34. protocol ImagePresentable { var imageName: String { get } } protocol TextFieldPresentable { var placeholder: String { get } var text: String { get } func onTextFieldDidEndEditing(textField: UITextField) }
  35. 35. extension TextPresentable { var textColor: UIColor { return .blackColor() } var font: UIFont { return .systemFontOfSize(17) } }
  36. 36. !!! class SwitchWithTextTableViewCell<T where T: TextPresentable, T: SwitchPresentable>: UITableViewCell { private var delegate: T? func configure(withDelegate delegate: T) { // configure views here } }
  37. 37. extension MinionModeViewModel: TextPresentable { var text: String { return "Minion Mode" } var textColor: UIColor { return .blackColor() } var font: UIFont { return .systemFontOfSize(17.0) } }
  38. 38. 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!") } } }
  39. 39. let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell<MinionModeViewModel> let viewModel = MinionModeViewModel() cell.configure(withDelegate: viewModel) return cell
  40. 40. !"#
  41. 41. "Change is the only constant." — Unknown
  42. 42. class SwitchWithTextTableViewCell<T where T: TextPresentable, T: SwitchPresentable, T: ImagePresentable>: UITableViewCell { }
  43. 43. extension MinionModeViewModel: ImagePresentable { var imageName: String { return "minionParty.png" } }
  44. 44. !"
  45. 45. > Use Protocols to Configure Your Views > Use Protocol Extensions for Defaults > Use ViewModels to Provide Data for the Protocols
  46. 46. HOW CAN WE MAKE THIS BETTER?

More Related Content

Related Books

Free with a 30 day trial from Scribd

See all

×