Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

self.tableView.reloadData() not working in Swift

I'm attempting to learn Swift & the basics of iOS dev at the same time, so bear with me. I've got a TableViewController that is firstly parsing a local JSON file and rendering it's very simple data into TableViewCell and SectionHeaderViews. Within the same TableViewController, I'm making a call to a JSON endpoint, which is returning data, which I am then setting to variables so I can access what I actually want to get at (the API structure is less than desirable). So, I finally set the proper data to be self.tableData and then call self.tableView.reloadData() but nothing happens. What gives?

import UIKit  class BusinessTableViewController: UITableViewController {      var data: NSMutableData = NSMutableData()     var tableData: NSArray = NSArray()      @lazy var Business: NSArray = {         let pathTCT = NSBundle.mainBundle().pathForResource("TCT", ofType: "json")         let data = NSData.dataWithContentsOfFile(pathTCT, options: nil, error: nil)         return NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as NSArray         }()      override func viewDidLoad() {         super.viewDidLoad()          navigationItem.titleView = UIImageView(image: UIImage(named: "growler"))          tableView.registerClass(BeerTableViewCell.self, forCellReuseIdentifier: "cell")         tableView.separatorStyle = .None          fetchKimono()     }      override func numberOfSectionsInTableView(tableView: UITableView!) -> Int { //        return Business.count         return 1     }      override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {         let biz = Business[section] as NSDictionary         let results = biz["results"] as NSDictionary         let beers = results["collection1"] as NSArray         return beers.count     }      override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {         let cell = tableView!.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath!) as BeerTableViewCell         if let path = indexPath {             let biz = Business[path.section] as NSDictionary             let results = biz["results"] as NSDictionary             let beers = results["collection1"] as NSArray             let beer = beers[path.row] as NSDictionary              cell.titleLabel.text = beer["BeerName"] as String         }          return cell     }      override func tableView(tableView: UITableView!, titleForHeaderInSection section: Int) -> String! {         let biz = Business[section] as NSDictionary         return biz["name"] as String     }      override func tableView(tableView: UITableView!, viewForHeaderInSection section: Int) -> UIView! {         let biz = Business[section] as NSDictionary         let view = LocationHeaderView()         view.titleLabel.text = (biz["name"] as String).uppercaseString         return view     }      override func tableView(tableView: UITableView!, heightForHeaderInSection section: Int) -> CGFloat {         return 45     }      func fetchKimono() {         var urlPath = "names have been changed to protect the innocent"         var url: NSURL = NSURL(string: urlPath)         var request: NSURLRequest = NSURLRequest(URL: url)         var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)          connection.start()     }      func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {         // Recieved a new request, clear out the data object         self.data = NSMutableData()     }      func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {         // Append the recieved chunk of data to our data object         self.data.appendData(data)     }      func connectionDidFinishLoading(connection: NSURLConnection!) {         // Request complete, self.data should now hold the resulting info         // Convert the retrieved data in to an object through JSON deserialization         var err: NSError         var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options:    NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary         var results: NSDictionary = jsonResult["results"] as NSDictionary         var collection: NSArray = results["collection1"] as NSArray         if jsonResult.count>0 && collection.count>0 {             var results: NSArray = collection as NSArray             self.tableData = results             self.tableView.reloadData()         }     } } 
like image 452
chandlervdw Avatar asked Jun 09 '14 02:06

chandlervdw


People also ask

What does Tableview reloadData do?

reloadData() :Reloads the rows and sections of the table view. Description : 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.

What is Tableview?

A table view displays a single column of vertically scrolling content, divided into rows and sections. Each row of a table displays a single piece of information related to your app.


1 Answers

You'll need to reload the table on the UI thread via:

//swift 2.3 dispatch_async(dispatch_get_main_queue(), { () -> Void in     self.tableView.reloadData() })  //swift 5 DispatchQueue.main.async{     self.tableView.reloadData() } 

Follow up: An easier alternative to the connection.start() approach is to instead use NSURLConnection.sendAsynchronousRequest(...)

//NSOperationQueue.mainQueue() is the main thread NSURLConnection.sendAsynchronousRequest(NSURLRequest(URL: url), queue: NSOperationQueue.mainQueue()) { (response, data, error) -> Void in     //check error     var jsonError: NSError?     let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &jsonError)     //check jsonError     self.collectionView?.reloadData() } 

This doesn't allow you the flexibility of tracking the bytes though, for example you might want to calculate the progress of the download via bytesDownloaded/bytesNeeded

like image 186
noobular Avatar answered Oct 24 '22 19:10

noobular