1

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)
}
Wez
  • 10,555
  • 5
  • 49
  • 63
Jan Moravek
  • 23
  • 1
  • 3
  • https://stackoverflow.com/questions/26082072/calling-function-from-another-class-swift – iDeveloper Dec 19 '17 at 14:41
  • Would you mind marking an accepted answer or adding a comment to the answers saying what needs to be improved? Thanks! – Blake Dec 20 '17 at 14:24

2 Answers2

1

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.

returnVoid
  • 604
  • 1
  • 9
  • 17
  • `@IBOutlet weak var cellTableView: UITableView!` Answer from Blake solve the problem. Thx anyway, I definitely will look into delegation more. – Jan Moravek Dec 20 '17 at 14:32
0

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.

Blake
  • 122
  • 1
  • 7
  • Thx! This solves the problem. But I don't understand why `getData.delegate = self` have to be placed inside viewDidLoad. – Jan Moravek Dec 20 '17 at 14:31
  • In the updateCoinData function you reference self.delegate. If you don't set the delegate of getData to the HomeViewController then self.delegate will be nil and didFinishGetData will never be called. If that's not called then your tableview will never get reloaded. Make sense? – Blake Dec 20 '17 at 21:12
  • Yes, make sense. – Jan Moravek Dec 22 '17 at 13:47