1

I am trying to follow the patten seen here: https://www.objc.io/issues/1-view-controllers/lighter-view-controllers/ and have also checked out this question here: Separating Data Source to another class in Swift

I have the following code:

class ApplicationsViewController: UIViewController {

    @IBOutlet var tableView: UITableView!
    let tableViewDataSource = ApplicationTableDataSource()

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    required init?(coder aDecoder: NSCoder) {
        //fatalError("init(coder:) has not been implemented")
        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        setupView()
    }

    func setupView() {
        tableView.dataSource = tableViewDataSource
    }
}

However what I don't fully understand what is the best way to communicate / pass data into the data source.

As an example lets imagine that the app starts and we have no data in our data source. Inside our ApplicationTableDataSource class we have a method called setApplicationData. Inside the viewController we click an add button which adds a new application for a job:

func buttonPressed() {
    let data = NSData()        

    //Here we want to add the data to array in data source

    // We can't do the following as tableView.dataSource doesn't know about the setApplicationData method:
    tableView.dataSource.setApplicationData(data)

    // We could do: 
    tableViewDataSource.setApplicationData(data)
}

I am not sure if this is the best way to update the data source.

Is there a better way to handle updating the data source?

Community
  • 1
  • 1
pls
  • 1,302
  • 1
  • 20
  • 40
  • what is the actual data source that you are using? is it just a static array, data pulled from core data, a network request?. The UITableViewDataSourceDelegate provides everything you need to provide a data source to a table view, you do not need to set data, just tell the tableview that something has changed. – Scriptable May 20 '16 at 11:20
  • Yeah that makes sense. It will be core data. However this is more of a generic question. Someone using a button to add something. The controller handles the button press. However one needs to update the underlaying model which in this case is an Array in the dataSource class. How would that work? – pls May 20 '16 at 11:30
  • Also does that mean that the data source class talks directly to core data or the networking layer? – pls May 20 '16 at 11:32

1 Answers1

0

I would highly recommend looking at NSFetchedResultsController if you are using core data and displaying this information in a table view.

I used this guide the first time I used it and found it to be a very effective solution.

When a user adds new information into the core data table that matches the query you have for displaying data, the tableview will automatically insert the row for you.

If you want to keep it simple and use an array, you can just append new data into the array and either call reloadData on the tableView or insertRowsAtIndexPaths. This SO answer will help you on that approach.

Just to give you a basic idea on how you might use another file for the tableView data source, see below:

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var dataSource = TBDataSource()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        tableView.dataSource = dataSource
        tableView.delegate = self

        dataSource.insertData("Data Row 1")
        dataSource.insertData("Data Row 2")
        dataSource.insertData("Data Row 3")
        dataSource.insertData("Data Row 4")
    }
}

class TBDataSource: NSObject, UITableViewDataSource  {

    var data = [String]()

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

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cell")!
        cell.textLabel?.text = data[indexPath.row]
        return cell

    }

    func insertData(str:String) {
        data.append(str)
    }
}

This is pretty much the minimum setup to provide data to your table from an external class. if you add data in after the intial load you would need to call reloadData or insertRowAtSection if you aren't using NSFectchedResultsController

Community
  • 1
  • 1
Scriptable
  • 17,875
  • 4
  • 50
  • 65