0

I am trying to fetch data from Parse and populate a table view controller. I have the following defined in the VC:

class OrdersViewController: UITableViewController{


    /*************************Global Objects************************/
    var userObject = UserClass()
    var utilities = Utilities()
    var orderObject = OrderClass()
    var objectsArray:[PFObject]!
    /*************************UI Components************************/

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        tableView.delegate = self
        tableView.dataSource = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        SwiftSpinner.show("Please Wait...Populating Table")

        let query = PFQuery(className:"Orders")
        query.whereKey("appUsername", equalTo:PFUser.currentUser()!["appUsername"])
        query.findObjectsInBackgroundWithBlock {
            (objects: [PFObject]?, error: NSError?) -> Void in

            if error == nil {
                SwiftSpinner.hide()
                self.objectsArray = objects
            } else {
                SwiftSpinner.hide()

                // Log details of the failure
                print("Error: \(error!) \(error!.userInfo)")
            }
        }

        SwiftSpinner.hide()
    }

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

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return objectsArray.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "cell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! OrderCell

        let row = indexPath.row
        cell.orderRetailerName.text = objectsArray[row]["nameRetailer"] as? String
        cell.status.text = objectsArray[row]["status"] as? String
        cell.dueDate.text = objectsArray[row]["dueDate"] as? String

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        /*tableView.deselectRowAtIndexPath(indexPath, animated: true)

        let row = indexPath.row
        print("")*/
    }

}

in the viewWillAppear I am trying to fetch the data from the Parse backend and populate the table with it. When I run the program, I am getting the following error:

fatal error: unexpectedly found nil while unwrapping an Optional value

the error is caused by objectsArray.count line in numberOfRowsInSection. Fair enough...It is trying to get the count but clearly the array is empty because the job of fetching data is running in background and isn't completed yet. This is what I need help with. Am I placing the fetching code in the right location (i.e. viewWillAppear)? If not, where should I put it instead to ensure it executes before the table actually attempts loading.

Thanks,

1 Answer 1

1

You have to initialize the PFObject array like the others.

var objectsArray = [PFObject]()

and you have to call reloadData() on the table view instance on the main thread right after populating objectsArray.

query.findObjectsInBackgroundWithBlock {(objects: [PFObject]?, error: NSError?) -> Void in
     if error == nil {
        self.objectsArray = objects!
        dispatch_async(dispatch_get_main_queue()) {
          self.tableView.reloadData()
        }
     } else {
        // Log details of the failure
        print("Error: \(error!) \(error!.userInfo)")
     }
     SwiftSpinner.hide()
}
Sign up to request clarification or add additional context in comments.

6 Comments

You mean that there is a way to actually place the fetching code in the initialization itself? I am relatively new to the language
In line 5 you are declaring the array but not initializing it. See the syntax difference.
yes I realized that that's why I modified my earlier comment. Is there an example I can look at where it shows an initialization and then how I would cann reloadData()?
yes thanks....making more sense now to me....except where would this code be placed? that was partially the issue at the beginning
If objectsArray is initialized exactly as suggested in my answer (as non optional) there can't be an error in numberOfRowsInSection because the variable is non optional and has a defined state.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.