SRewip SRewip - 6 months ago 21
JSON Question

Global variable doesn't store any data in anonymous method

trying to get nasa.gov asteroid's data. There is a

asteroids
global variable of array of Asteroid instances. There is about 1000 occurrences in the
jsonData
variable. When I append the occurrence at the line
self.asteroids.append()
, I can see it's adding. When the anonymous
completionHandler
method ends, variable
self.asteroids
is empty again, so it doesn't reload no data.

It doesn't make any sense to me since
asteroids
is a global variable and it should store any data appended to it. Can anyone help?

class ViewController: UITableViewController {

var asteroids = [Asteroid]()

override func viewDidLoad() {
super.viewDidLoad()

let connectionString: String = "https://data.nasa.gov/resource/y77d-th95.json"
let url = NSURL(string: connectionString)!

let session = NSURLSession.sharedSession()

let task = session.dataTaskWithURL(url, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) in
do {
let jsonData = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions())
for index in 0 ... (jsonData.count - 1) {
self.asteroids.append(Asteroid(name: jsonData[index]["name"] as! NSString as String))
}
} catch {
print("Error")
return
}
})

task.resume()

self.tableView.reloadData()
}

Answer

Put the table view's reloadData method in the completion block, after the asteroids array have been modified. Another way would be to reloadData in asteroid didSet method:

var asteroids = [Asteroid]() {
  didSet {
    dispatch_async(dispatch_get_main_queue()) {
      self.tableView.reloadData()
    }
  }
}

Code of the completion handler is called after the end of scope of viewDidLoad function. Because the dataTaskWithURL is an asynchronous operation.