Ahmed Onawale Ahmed Onawale - 11 months ago 88
Swift Question

UITableView got rendered before data from API returned using SwiftyJSON and Alamofire

when I call callapi() function in viewDidLoad(), the println() in callapi prints the posts array with Post objects inside it, however the println() inside the viewDidLoad() function prints an empty array. Also when I build the project I get this error "fatal error: Array index out of range". the println() statement in the tableView function prints an empty array also. It seems the table got rendered before the data from the API arrived how can I solve this?

var posts = [Post]()

override func viewDidLoad() {

func callapi(){
request(.GET, "url")
.responseJSON { (request, response, data, error) in
let json = JSON(data!)
if let jsonArray = json.array {
for post in jsonArray {
var onepost = Post(id:post["id"].stringValue,


override func tableView(tableView: UITableView, cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier,
forIndexPath: indexPath) as! CustomTableViewCell

let post = self.posts[indexPath.row]
// Configure the cell...
cell.titleLabel!.text = self.posts[indexPath.row].title
cell.postLabel.text = post.post
return cell

Rob Rob
Answer Source

When viewDidLoad is called, it starts the asynchronous callapi, but by the time viewDidLoad finishes, posts is still empty. But the table view is still going to proceed with its initial load process, even though posts hasn't been populated, so you must ensure that tableView:numberOfRowsInSection: returns zero at this point.

Later, callapi finishes the Alamofire GET request and calls reloadData. Only at this point should tableView:numberOfRowsInSection: return non-zero value.

Bottom line, make sure that tableView:numberOfRowsInSection: returns the actual number of entries in posts, and the problem should be resolved.