Protocol-Oriented MVVM

  • View
    3.748

  • Download
    0

  • Category

    Software

Preview:

Citation preview

POMVVM@NATASHATHEROBOT

"Swift Is a Protocol-Oriented Programming Language"

— Dave Abrahams, Professor of Blowing-Your-Mind

UITableViewDelegate UITableViewDataSourceUITextFieldDelegateNSURLSessionDelegateCLLocationManagerDelegateMCSessionDelegate

!

!

!

!

Artsy Engineering: MVVM in Swift

THE PROBLEMclass SwitchWithTextTableViewCell: UITableViewCell {

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

}

PROTOCOLS TO THE RESCUE !

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

extension SwitchWithTextCellProtocol {

var switchColor: UIColor { return .purpleColor() }

}

class SwitchWithTextTableViewCell: UITableViewCell {

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

}

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

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

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

return cell

!

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

// SwitchWithTextTableViewCell

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

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

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

// SettingsViewController

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

!

@MHOLLEMANS: MIXINS AND TRAITS IN SWIFT 2.0

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

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

! "

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

protocol ImagePresentable { var imageName: String { get }}

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

func onTextFieldDidEndEditing(textField: UITextField)}

extension TextPresentable {

var textColor: UIColor { return .blackColor() }

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

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

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

}

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

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

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

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

!"#

"Change is the only constant."— Unknown

!"

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

> Use ViewModels to Provide Data for the Protocols

HOW CAN WE MAKE THIS BETTER?