theDC
theDC

Reputation: 6484

Swift - How to create a table view based on data downloaded asynchronously?

My app downloads json from the web, draw the map with pins and present the data in table view.

Map is not a problem because I write my custom function to draw the map and invoke it right after the dispatch_async(dispatch_get_main_queue() line which works perfectly - map is waiting for the data to be downloaded. However, the problem comes when I want to do the same with table view.

My code is quite long so I'm going to show just the short snippets to catch the idea of the issue.

I tried the following modification:

    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
                // Do any additional setup after loading the view, typically from a nib.
                self.tableView.backgroundColor = UIColor.clearColor();
                self.tableView.delegate = self;
                self.tableView.dataSource = self;

But unfortunately it doesn't help in any way - table view is again loading before the data is downloaded which leads to an empty table.

Table view uses its own predefined functions such as:

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

And putting them inside the asynchornous task is not possible without errors

My question is: how to deal with that kind of stuff(I mean situation when you want an element such as table view "wait" for the data to be downloaded first and you cannot put it inside the downloading task)?

I hope I managed to present the problem relatively clearly, Thanks in advance

Upvotes: 3

Views: 3995

Answers (1)

sapi
sapi

Reputation: 10224

The table view works through the delegate and the data source. By setting those properties, you're telling the table view where to report events, and where to look for its data.

Because these methods are called 'by' the table view (or at least sent by the UI thread), you don't run them directly. What you do instead is set the delegate and data source (as you have done), and then call methods on the table view itself to tell it when to check for new data.

In particular, you should look at this section of the documentation. You may be able to get away with just asynchronously dispatching self.tableView.reloadData() (provided the rest of your app is aware of the new data in the callback methods that you've identified).


The basic idea is that your UITableViewDataSource knows how to populate the table view with information from some data structure (eg, you might have an array as a property).

When the underlying data changes (eg, because you've downloaded something from the web), you change this data structure (eg, replace the array) and tell the appropriate parts of the table view to reload.

That will then call the various UITableViewDataSource methods, which will re-populate the table view with the new data.

Upvotes: 7

Related Questions