I am using Parse.com to store data for an iOS app. The code below successfully retrieves all values in a nested array belonging to a PFObject “game”. However, if I need to query for another array (at the same level as “winners” (say “losers”) i cannot get it to work, and not all the values in the array losers gets populated. I suppose i could do them all on the main thread and not try to nest the fetches (nested blocks) but i’m wondering if:
1) Is the way i’m storing my data prohibiting me from using Parse’s built in query/fetch functionality properly? Data stored as:
PFObject * newGame = [PFObject objectWithClassName:@"Game"];
NSArray * winner = [NSArray arrayWithObjects:[_allPlayersPFDictionary objectForKey:[playerData objectAtIndex:0]], [playerData objectAtIndex:1], nil];
[_gamePF addObject:winner forKey:@"winners"];
2) Is there a better, cleaner way to do the query and get ALL the values of all nested arrays of data in a query? Again, winners is not a PFObject, but is an array of array of PFObject of 2 different types ([PFObject fetchAll:(NSArray *)winnersArray] does not work, because all objects in the Array must be of the same ‘type’ of PFObject). I store it this way because each winning player has another PFObject (1 to many) “powers” associated with them.
Here is the query that works but i can’t figure out how to add “losers” to it and properly populate all data in the background.
PFQuery * gamesQuery = [PFQuery queryWithClassName:@"Game"];
[gamesQuery orderByDescending:@"createdAt"];
gamesQuery.limit = 30;
[gamesQuery findObjectsInBackgroundWithBlock:^(NSArray * theGames, NSError * error) {
if (error) {
NSLog(@"ERROR: There was an error with the Query to get Games!");
} else {
for (PFObject * aGame in theGames) {
for (NSArray * aWinner in [aGame objectForKey:@"winners"]) {
[[aWinner objectAtIndex:0] fetchIfNeededInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (error) {
NSLog(@"ERROR: There was an error with the Query to get Player in winnersArray!");
} else {
[PFObject fetchAllIfNeededInBackground:[aWinner objectAtIndex:1] block:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(@"ERROR: There was an error with the Query to get Powers in winnersArray!");
} else {
[_gamesPF addObject:aGame];
NSLog(@"Games from viewDidLoad %@", _gamesPF);
[_tableView reloadData];
}
}];
}
}];
}
}
}
}];
Well… i feel kinda stupid. Definitely much easier to use Parse in an object oriented manner for the data model. Was able to easily solve it by remodeling the data to be:
Game (PFObject *) has:
where a winner is created as:
Which then makes the query much easier and involves only one background block like so: