3

I get data by Alamofire in viewDidLoad, then put it into answerArray. However, before Alamofire connection, the numberOfRowsInSection is invoked and returns 0. How can I get data by Alamofire first, then get eventArray.count at numberOfRowsInSection?

var answerArray = NSMutableArray()

override func viewDidLoad() {
let parameters = [
        "id":questionNum
    ]

    Alamofire.request(.POST, "http://localhost:3000/api/v1/questions/question_detail",parameters: parameters, encoding: .JSON)
        .responseJSON { (request, response, JSON, error) in
            println(JSON!)
            // Make models from JSON data
            self.answerArray = (JSON!["answers"] as? NSMutableArray)!
    }
    self.tableView.reloadData()
}


override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return answerArray.count

}
SwiftArchitect
  • 47,376
  • 28
  • 140
  • 179
Toshi
  • 1,293
  • 3
  • 19
  • 37

2 Answers2

7

I think more elegant way would be reloading tableView every time you assign to answerArray so that tableView will be updated automatically whenever you get a response from your API.

Move self.tableView.reloadData() into didSet callback.

var answerArray = NSMutableArray() {
    didSet {
        self.tableView.reloadData()
    }
}
Community
  • 1
  • 1
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
  • Excellent method. I do think that that was a bug in @yomihito's code though. But very clever technique nonetheless. Using this approach, the original `self.tableView.reloadData()` should go away entirely. – SwiftArchitect Jul 19 '15 at 06:27
  • Yep, this is correct (+1). But it's worth noting that this is just a tad fragile, because its proper operation is dependent upon the implementation details of the `responseJSON` completion handler closure. What if that closure didn't replace `answerArray`, but rather just removed the old objects and added the new ones? This wouldn't work in that scenario. One should always be circumspect of `didSet` with mutable objects because it does not detect changes within the object, only if the object is replaced entirely. Plus, in MVC world, model objects really shouldn't be updating view objects. – Rob Jan 29 '17 at 18:41
6

The behavior is normal. UITableView delegate invokes numberOfRowsInSection as needed.

All you need is to trigger self.tableView.reloadData() to refresh the table.

Alamofire.request(.POST, "http://localhost:3000/api/v1/questions/question_detail",parameters: parameters, encoding: .JSON)
    .responseJSON { (request, response, JSON, error) in
        println(JSON!)
        // Make models from JSON data
        self.answerArray = (JSON!["answers"] as? NSMutableArray)!
        self.tableView.reloadData()
}
SwiftArchitect
  • 47,376
  • 28
  • 140
  • 179