tonytran tonytran - 6 months ago 34
Swift Question

is passing argument a viewmodel or a protocol

The codes are taken from Protocol Oriented MVVM and this is how

ViewModel
looks like :

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

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

var switchColor: UIColor {
return .yellowColor()
}
}


I understand this part. Basically,
MinionModeViewModel
are overriding some default behaviors of
SwitchWithTextCellDelegate
and
SwitchWithTextCellDelegate


Next the author is configuring the cell by passing
viewModel
as arguments :

SettingsViewController.swift

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


However, at
SwitchWithTextTableViewCell
, the arguments of
configure
method are
SwitchWithTextCellDataSource
and
SwitchWithTextCellDelegate


func configure(withDataSource dataSource: SwitchWithTextCellDataSource, delegate: SwitchWithTextCellDelegate?) {
self.dataSource = dataSource
self.delegate = delegate

label.text = dataSource.title
switchToggle.on = dataSource.switchOn
// color option added!
switchToggle.onTintColor = delegate?.switchColor
}


Im new to Swift. Can someone please explain


  1. what are the names and their meaning
    dataSource
    and
    delegate
    of the
    configure
    method in
    SwitchWithTextTableViewCell
    . Are they
    External Parameter Names
    .

  2. why the type of passing arguments of
    configure
    method are different :
    view model
    vs
    protocols
    types


Answer

First of all MinionModeViewModel is not overriding the default behaviours of SwitchWithTextCellDelegate and SwitchWithTextCellDelegate.

The term overriding is used along with the inheritance. Example

class A {
  func someFunction() {
  }
}
class B:A {
  override func someFunction() {
  }
}

Here class B is subclass of class A and thus if class B should provide different implementation of method someFunction than its class A it should override it and provide different implementation.

Protocols are different. It's kind of abstract class. Protocols are just set of rules. So when some class or struct conforms to a protocol it means that they should implement all the required methods or properties stated in the protocol definition.

Example:

protocol SwitchWithTextCellDelegate {

  func onSwitchTogleOn(on: Bool)

  var switchColor: UIColor {get}
}

Now any structs or class that conforms to protocol SwitchWithTextCellDelegate should implement onSwitchToggleOn method and also should have a property switchColor which will have a getter.

Like you have done:

extension MinionModeViewModel: SwitchWithTextCellDelegate {
    func onSwitchTogleOn(on: Bool) {
    }

    var switchColor: UIColor {
        return someColor
    }
}

Explanation for the method

1. func configure(withDataSource dataSource: SwitchWithTextCellDataSource, delegate: SwitchWithTextCellDelegate?)

dataSource: In this parameter we can pass any class or struct that conforms to protocol SwitchWithTextCellDataSource protcol

delegate: In this parameter we can pass any class or struct that conforms to protocol SwitchWithTextCellDelegate

Now it might be confusing that the author of the tutorial has passed same object in both parameter. Why not pass it as a single parameter?

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

It's because here MinionModeViewModel is conforming to both SwitchWithTextCellDataSource and SwitchWithTextCellDelegate protocol so we can pass same object in both parameter. But this method has the flexibility to pass any object that conforms to those protocols.