'Array does not connect with the tableView(numberOfRowsInSection) method

I have an array which I will store all data that I get from http request and display them on tableView but it seems that tableView(numberOfRowsInSection) does not recognize the change in the array because the count remains as 0.

class OrdersViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    
    var arr = [[String: AnyObject]]()
    var selectedIndex = -1
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Do any additional setup after loading the view.
        let baseUrl = "my url"
        let consumer_key = "consumer_key"
        let consumer_secret = "consumer_key"
        let url = "\(baseUrl)?consumer_key=\(consumer_key)&consumer_secret=\(consumer_secret)&status=processing"
        
        let headers2 = ["Accept": "application/json"]
        Alamofire.request(url, headers: headers2)
            .responseJSON { response in
                    self.arr.append(data from request)
                }
        }
        
        let url2 = "\(baseUrl)?consumer_key=\(consumer_key)&consumer_secret=\(consumer_secret)&status=pending"
        Alamofire.request(url2, headers: headers2)
            .responseJSON { response in
                    self.arr.append(data from request)
                    print("arr", self.arr)
                }
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        print("after request", self.arr)
        return self.arr.count
    }
}
// and some other code...

I do get data from the http request successfully and it gets updated in my Alamofire call but "after request" keeps printing empty array. What's going on here?



Solution 1:[1]

You need to call tableView.reloadData() after changing your self.arr property. The corresponding documentation provides further details:

Call this method to reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. For efficiency, the table view redisplays only those rows that are visible.

If you plan on changing your self.arr property in many places, you could alternatively add a property observer to it:

var arr = [[String: AnyObject]]() {
    didSet { tableView?.reloadData() } 
}

...so you wouldn't need to copy-and-paste the same code all around ;-)

Solution 2:[2]

I would recommend you to move your request and response logic in one function and then call that function from viewDidAppear instead of viewDidLoad and just after the call reload your tableview using reloadData()

Solution 3:[3]

use this code inside the Viewdidload

dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
 } 

instead of

tableView.reloadData()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Joe
Solution 3 Vignesh J