bubu
bubu

Reputation: 11

iOS - UITableView delegate & datasource in MVP design

I am trying to implement UITableViewController using Model-View-Presenter. Since I am new to this concept, I am very confused by how to separate UITableView's data source protocols from UIViewController.

Many articles agree with the idea that View+Viewcontroller needs to be dumb and only consider about UIs and their layouts. On the other hand, Presenter needs to be a facilitator between view and model and also implement logic, but they stated to not include UIKit since it does not directly manipulate UIs. And here is where my confusion kicks in.

When we implement UITableView, we have to implement two protocols: UITableViewDelegate and UITableViewDataSource, especially the data source.

I assume delegate belongs to View portion and passes events to Presenter when receives user action.

However, to implement UITableViewDataSource, we must have some model that table view utilizes. That being said, I can only think of two ways to somehow fit into MVP.

  1. Pass Model value to UITableView from Presenter, and let it be read-only valuable in the view for the sake of data source (such as create a row for a specific index). But then I think it violates the MVP concept since the Model value is direct access by View.

  2. Let presenter be the data source. But since Presenter should not import UIKit, I think import UIKit and implement UITableViewDatasource also violates the MVP concept.

So long story short, I am confused where and how to appropriately implement UITableDatasource... If anyone knows this concept well, please share your knowledge. Thank you in advance!

Upvotes: 1

Views: 1539

Answers (2)

Inal Bansal
Inal Bansal

Reputation: 1

Create a cell item in UIViewController:

private var cellItems: [CarCellItem]

This cell item array will be created in presenter (by fetching data from server or local database).

Here, we are not using the model received from server or local database; rather we are creating cellItem array from the model and send this cell item array back to view controller

Implement datasource and delegates in UIViewController only:

func tableView(_ tableView: UITableView, numberOfRowsInSection
section: Int) -> Int {
    return cellItems.count
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->    UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: 
  Constant.cellIdentifier, for: indexPath) as! CarListCell
    cell.configure(cellItem: cellItems[indexPath.row])
    return cell
}

Create cell like this:

class CarListCell: UITableViewCell  {
 @IBOutlet weak var name: UILabel!
  func configure(cellItem: CarCellItem){
    name.text = cellItem.name
   } }
final class CarCellItem {

// MARK:- Properties

var name: String
init(name: String) {
    self.name = name }
}

Upvotes: 0

Fırat Yenidünya
Fırat Yenidünya

Reputation: 274

First option is using adapter pattern with MVP. You can conform UITableViewDelegate and UITableViewDataSource in adapter class. In this way you can separate tableView logic from ViewController and Presenter still won't include UIKit.

Upvotes: 1

Related Questions