Jan Moravek
Jan Moravek

Reputation: 23

Refresh a UITableView from another class in Swift

My goal is:

I have a class getData that is used to download data from the server then saves it to array. After that I want the class getData to be able to update the cellTableView in HomeViewController.

If I have all func in one swift file it works. But I want to used it multiple times and don't used same code in every UIViewController and I also want to get know how to use delegates.

I tried use this answer to similar problem.

Promblem:

For now code downloads and stores but not updates cellTableView.

HomeViewController:

import UIKit

class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, GetDataDelegate {

    let getData = GetData()

    ...


    override func viewDidLoad() {
        super.viewDidLoad()

        cellTableView.delegate = self
        cellTableView.dataSource = self

        cellTableView.register(UINib(nibName: "HomeCell", bundle: nil), forCellReuseIdentifier: "homeCell")

        for (n, _) in MyVariables.coinTickerArray.enumerated() {
            MyVariables.dataArray.append(HomeLabel(coinNameCell: MyVariables.coinNameArray[n], tickerCell: MyVariables.coinTickerArray[n]))
        }

        getData.storeData()
    }

    ...

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let coinCell = tableView.dequeueReusableCell(withIdentifier: "homeCell", for: indexPath) as! HomeCell

        ...

        return coinCell
    }

    ...

    @IBAction func refreshButtonPressed(_ sender: UIBarButtonItem) {
        getData.storeData()
        self.didFinishGetData(finished: true)
    }

    @IBAction func currencyControlPressed(_ sender: UISegmentedControl) {

        ...

        getData.storeData()
    }

}

GetData:

import UIKit
import Alamofire
import SwiftyJSON

class GetData {

    var delegate: GetDataDelegate?

    func downloadData(url: String, number: Int) {

        ...
    }

    func updateCoinData(json: JSON, number: Int) {

        ...

        self.delegate?.didFinishGetData(finished: true)
    }

    func storeData () {
        for (n, _) in MyVariables.coinTickerArray.enumerated() {

            MyVariables.finalURL = MyVariables.baseURL+MyVariables.coinTickerArray[n]+MyVariables.currentCurency
            downloadData(url: MyVariables.finalURL, number: n)

        }
    }  
}

View+GetDataDelegate:

import Foundation

extension HomeViewController: GetDataDelegate {
    func didFinishGetData(finished: Bool) {
        guard finished else {
            // Handle the unfinished state
            return
        }
        self.cellTableView.reloadData()
    }
}

GetDataDelegate:

import Foundation

protocol GetDataDelegate {
    func didFinishGetData(finished: Bool)
}

Upvotes: 1

Views: 783

Answers (2)

returnVoid
returnVoid

Reputation: 644

I can't tell from your posted code where cellTableView is declared. I believe every instance of cellTableView should be replaced with tableView. You are calling tableView in your dataSource and delegate methods but then you reload data with cellTableView.

You should also look into delegation more. It's a tough concept to get initially but once you do get it a task like this will be a breeze.

Upvotes: 1

Blake
Blake

Reputation: 107

Is didFinishGetData getting called? I assume it isn't since the tableview is not reloading. In the code that you pasted, you aren't setting the getData delegate equal to HomeViewController, which in this case is self. Add this code to your viewDidLoad and it should work:

getData.delegate = self

If that doesn't work, then you'll need to add more code because I can't tell at the moment when updateCoinData gets called, which calls your delegate method.

Upvotes: 0

Related Questions