I have a UIViewController with a tableView as a subview. The tableview will have 3 sections, and I used the answer to my question PFQueryTableViewController with 3 Sections to accomplish this, but the data is not getting loaded into the table. I am executing my query in the background in viewWillAppear. I fear that this is due to the nested query blocks. How can I fix this? Here is my code:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
PFQuery *gameQuery = [PFQuery queryWithClassName:@"Game"];
[gameQuery whereKey:@"players" equalTo:[PFUser currentUser]];
[gameQuery orderByDescending:@"createdAt"];
[gameQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error){
self.myTurn = [NSMutableArray array];
self.theirTurn = [NSMutableArray array];
self.gameOver = [NSMutableArray array];
self.allGames = [NSArray array];
for(PFObject *object in objects)
{
if([object objectForKey:@"isOver"] == [NSNumber numberWithBool:YES])
{
[self.gameOver addObject:object];
}
else
{
PFRelation *relation = [object relationForKey:@"whoseTurn"];
PFQuery *relQuery = [relation query];
[relQuery findObjectsInBackgroundWithBlock:^(NSArray *userObjects, NSError *error1){
NSMutableArray *arr = [NSMutableArray array];
for(PFUser *user in userObjects)
{
[arr addObject:user.objectId];
}
if([arr containsObject:[PFUser currentUser].objectId])
{
[self.myTurn addObject:object];
}
else
[self.theirTurn addObject:object];
}];
}
}
self.allGames = [NSArray arrayWithObjects:self.myTurn, self.theirTurn, self.gameOver, nil];
[self.tableView reloadData];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.allGames count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self.allGames objectAtIndex:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
PFObject *object = self.allGames[indexPath.section][indexPath.row];
cell.textLabel.text = [object objectForKey:@"numPlayers"];
return cell;
}
allGamesis initialized with 3 empty arrays at the time you callreloadData. Since your data structure is known (an array comprised of 3 arrays), why not initializing it with 3 empty arrays before running your Parse queries and then, in callback blocks, updating it directly (with proper thread synchronization) and finally callingreloadData? This will end up in callingreloadDatamuch more often, but iOS should be OK with it, and if not, you'll still be able to find optimizations later with your working code anyway.self.gameOver, but not for the other ones. Doesself.gameOveractually contain at least one object when you callself.allGames = [NSArray arrayWith...];? If not, try to put some data into Parse that would make an object appear in this array. The other two are getting filled in asynchronous blocks, so after theallGamesinitialization, probably, that's why they are still empty at that point.