Ayaal Uraankhay
Ayaal Uraankhay

Reputation: 49

tableView.reloadData() How to correctly reload data?

class ProductTableViewController: UITableViewController 
{
    var products = [Product]()

    override func viewDidLoad() {
        super.viewDidLoad()
        getData()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       return products.count // zero
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell", for: indexPath) as! ProductCell
        cell.userIdLabel?.text = "user id" + "$\(products[indexPath.row].userId)"
        cell.idLabel?.text = "id" + "$\(products[indexPath.row].id)"
        cell.titleLabel?.text = products[indexPath.row].title
        cell.bodyLabel?.text = products[indexPath.row].body
        return cell
    }

    func getData(){
        let url = URL(string: "https://jsonplaceholder.typicode.com/posts")
        URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
            guard let data = data, error == nil else { return }
            do {
                let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [[String:Any]]
                for post in json{
                    let product = Product()
                    product.userId = post["userId"] as! Int
                    product.id = post["id"] as! Int
                    product.title = post["title"] as! String
                    product.body = post["body"] as! String
                    self.products.append(product)
                }
                //OperationQueue.main.addOperation({ () -> Void in self.tableView.reloadData()})
            } catch let error as NSError {
                print(error)
            }
//HERE!!!
            OperationQueue.main.addOperation({ () -> Void in self.tableView.reloadData()})
        }).resume()
    }
}

When my UITableViewController executed first of all will implement func tableView and he will return zero count cause getData() didn't run yet and of course second tableView who returning my Cell will not implement.
And now, I wanna see what parsed my getData() in order to do I try to reload my tableView with OperationQueue.main.addOperation({ () -> Void in self.tableView.reloadData()})
but caught an error :

Thread1 :SIGABRT.

How I should correctly reload my tableView?

Upvotes: 1

Views: 4170

Answers (1)

xmhafiz
xmhafiz

Reputation: 3538

Try this

func getData(){
    let url = URL(string: "https://jsonplaceholder.typicode.com/posts")
    URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
        guard let data = data, error == nil else { return }
        do {
            let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [[String:Any]]
            for post in json{
                let product = Product()
                product.userId = post["userId"] as! Int
                product.id = post["id"] as! Int
                product.title = post["title"] as! String
                product.body = post["body"] as! String
                self.products.append(product)
            }
            // just reload here after finish appends
            self.tableView.reloadData()
        } catch let error as NSError {
            print(error)
        }
    }).resume()
}

Upvotes: 1

Related Questions