motivated
motivated

Reputation: 53

Swift 4, Json data doesn't appear in cells

I can't put data to the cells, I searched in different tutorials and it should work , I checked in debug area and data are downloaded but doesn't exist in cells, I tried also with custom cells but it doesn't work too. I have not got any error message, simply empty cells. Do you know maybe what can cause this issue? I spended much time for searching solution but I can't find anything, on every tutorial people do this similar to me.

struct Country: Decodable {
   let name: String  
}

class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var countries = [Country]()
    var liczba = Int()

    @IBOutlet var tv: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        json() {
            self.tv.reloadData()
        }

        tv.dataSource = self
        tv.delegate = self
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = countries[indexPath.row].name
        return cell
    }

    func json (completed: @escaping()->()) {
        let jsonUrl = "https://restcountries.eu/rest/v2/all"
        let url = URL(string: jsonUrl)

        URLSession.shared.dataTask(with: url!) { (data, response, error) in
            do {
                self.countries = try JSONDecoder().decode([Country].self, from: data!)
                let numer = self.countries.count
                self.liczba = numer
            }
            catch {
                print("error")
            }
        }.resume()
    }
}

Upvotes: 0

Views: 82

Answers (3)

vadian
vadian

Reputation: 285072

Since you are not returning anything from the closure I recommend to delete the completion handler and reload the table view on the main thread within the closure.

And don't forget to handle a potential error

func json() {
    let jsonUrl = "https://restcountries.eu/rest/v2/all"
    let url = URL(string: jsonUrl)

    URLSession.shared.dataTask(with: url!) { [unowned self] (data, response, error) in
        if let error = error { print(error); return }
        do {
            self.countries = try JSONDecoder().decode([Country].self, from: data!)
            self.liczba = self.countries.count
            DispatchQueue.main.async {
                self.tv.reloadData()
            }
        }
        catch {
            print("error")
        }
    }.resume()
}

and call the method in viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()

    tv.dataSource = self // I'd connect datasource and delegate in Interface Builder
    tv.delegate = self
    json()
}

Upvotes: 0

EmilioPelaez
EmilioPelaez

Reputation: 19892

You are never calling the completed closure of your json method, so self.tv.reloadData() will never be executed.

Add completed() after self.liczba = numer.

Upvotes: 1

Pablo Marrufo
Pablo Marrufo

Reputation: 885

It seems that you are having a problem with the sequentiality of your code. You are calling reloadData on your tableview but at that moment you don't have set the datasource yet.

try this:

tv.dataSource = self
tv.delegate = self

json() {
    self.tv.reloadData()
}

Upvotes: 1

Related Questions