Reputation: 2295
I have the following structure:
My User Table has a field called experienceArray
, which is just an Array of Pointers to another table called experience
. Every experience
object has got a Pointer to another table Sport
. Sport
is just a simple table containing a Title (String). I'm trying to show the title of each object in a tableview. Unfortunately I'm getting exceptions in my tableview delegate, where I'm assigning the title value to my tableview cell label.
var object : PFObject = self.chosenSports[indexPath.row]["sport"] as! PFObject
Here's what it says:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Key "title_en" has no data. Call fetchIfNeeded before getting its value.'
The message absolutely makes sense to me - it doesn't get the most inner child objects, only their objectIds.
Here's what I do:
var query = PFUser.query()
query!.includeKey("experienceArray")
query!.includeKey("experienceArray.Sport")
query!.includeKey("experienceArray.Sport.title_en")
query!.whereKey("objectId", equalTo: PFUser.currentUser()!.objectId!)
query!.findObjectsInBackgroundWithBlock { (result: [AnyObject]?, error:NSError?) -> Void in
println("sports result: \(result)")
var res = result as! NSArray
var user = res[0]
self.chosenSports = user["experienceArray"] as! NSMutableArray
self.sportsTableView.reloadData()
}
How would I change my code to receive all the information contained within the PFUser Object and all their children?
Upvotes: 0
Views: 515
Reputation: 2295
I decided to fetch all the children with cloud code and just call the cloud function from the App. This was pretty straightforward and turned out to be the best solution, because now there's less code on each system (iOS and Android)
Upvotes: 0
Reputation: 997
Can you try this and tell me if it works:
PFUser.currentUser().fetchIfNeeded { user, error in
if error == nil && user != nil {
if let sports = user["experienceArray"] as? [PFObject] {
let query = PFQuery(className: "Sport") // Change to correct name.
query.whereKey("objectId", containedIn: sports.map { $0.objectId })
query.findObjectsInBackgroundWithBlock { (results, error) -> Void in
// TODO: Use results
}
}
}
}
Of course since I don't know how you're saving stuff to iVars I included the code inside the block but you can simply assign it to an ivar. This should work.
EDIT: Changed code to make only 2 requests. Also note the code doesn't handle errors, but this should be easy to do.
Upvotes: 1