Mo Code Mo Code - 7 months ago 8
Swift Question

Swift string array keeps showing up empty

I've got a function that will connect to my parse database and go through all the user objects and append their names and emails to a string array for each category.

When I debug it it shows the arrays as having the correct values during the viewWillAppear function but when it comes down to returning the amount of rows in the array they are empty for some reason.

Any idea what is causing this?

Here is my code

import UIKit
import Parse

class ContactTableViewController: UITableViewController {

//arrays to hold user's name and email
var users_names = [String]()
var users_emails = [String]()


override func viewWillAppear(animated: Bool){

//Load user email and name
let query: PFQuery = PFUser.query()!

query.findObjectsInBackgroundWithBlock {
(objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) users.")
// Do something with the found objects
if let user_objects = objects {
for user in user_objects {
self.users_names.append(user.valueForKey("name") as! String)
self.users_emails.append(user.valueForKey("email") as! String)
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
self.users_names.removeAtIndex(1)
self.users_emails.removeAtIndex(1)
self.tableView.reloadData()
}
}

override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(red: 0.8353, green: 0.9098, blue: 0.902, alpha: 1.0)
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}



// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}

//return number of rows in table
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users_names.count
}


The problem is cellForRowAtIndexPath is running and populating the table before viewWillAppear() runs and fetches the data into the array.

I've tried adding this at the start of viewWillAppear

UIApplication.sharedApplication().beginIgnoringInteractionEvents()


And Then .endIgnoringInteractionEvents() at the end of viewWillAppear but that didn't fix it either.

Answer

You are calling self.tableView.reloadData() from your block, which is running on a background thread. All UI-related operations must run on the main thread. Try wrapping the call to reload like this:

self.users_names.removeAtIndex(1)
self.users_emails.removeAtIndex(1)
dispatch_async(dispatch_get_main_queue()) { 
    self.tableView.reloadData()
}