I am trying to populate a PFQueryTableViewController with Question objects from my Parse backend. How do I implement blocks within this method?
- (PFQuery *)queryForTable // I'm having issues with using the method "findObjectInBackgroundWithBlock" in this method.
{
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
[query fromLocalDatastore];
[query orderByDescending:@"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *parseQuestions, NSError *error) { // Fetch from local datastore
if (parseQuestions != nil) {
NSMutableArray *mutableParseQuestions = [parseQuestions mutableCopy];
self.questions = mutableParseQuestions; // if Set local array to fetched Parse questions
} else {
if ([InternetReachabilityManager isReachable]) {
[query findObjectsInBackgroundWithBlock:^(NSArray *parseQuestions, NSError *error) { // Fetch from Cloud
NSMutableArray *mutableParseQuestions = [parseQuestions mutableCopy];
self.questions = mutableParseQuestions; // if Set local array to fetched Parse questions
[Question pinAllInBackground:parseQuestions]; // Save query results to local datastore
}];
}
}
}];
return query;
}
When blocks are in this method I get this error.
Is this because queryForTable is already a background process? Should I just use
[query findObjects]
Also, I'm trying to implement reachability into my fetch.
- Try fetching from local datastore
- Load data into table if they are there else switch to the network
- Call block if network is available
- Save the results of the network fetch into the local datastore
I know that this method is supposed to automatically assign objects it fetches to rows but I don't know how to work with it if we're passing around a PFObject subclass object. This is my explanation for the arrays.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
self.question = [self.questions objectAtIndex:indexPath.row]; // Save one question from row
static NSString *identifier = @"QuestionsCell";
QuestionsCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[QuestionsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
[cell setQuestion:self.question]; //
return cell;
}
This is how I use the fetched array to populate the tableView.
So my questions:
- Why can't I call a block inside of queryForTable?
- Is there any way I can make this simpler by using queryForTable's automatic assigning of objects to rows?
- If the internet is unreachable and the local datastore is empty what should I do?
There is no reason to call your query in that function. You're supposed to create a query and then return it. PFQueryTableViewController does the actual handling of the request. Read the documentation here: https://parse.com/docs/ios/api/Classes/PFQueryTableViewController.html#//api/name/queryForTable
Once you're in the cellForRowAtIndexPath method you can call objectAtIndexPath: which will you give you the object you need and then use the data from it to set up your cell.
You do this (semi-pseudo code)