Recently i came across a problem when using the Parse iOS SDK. Unknown to me, the Parse PFQuery object will only return 100 results by default. Which unfortunately, i found out the hard way when one of my apps stopped returning results when the table hit the 100 rows mark. As the Parse documentation says hidden away somewhere:
You can limit the number of results by setting limit. By default, results are limited to 100, but anything from 1 to 1000 is a valid limit:
So what if we want more than 100 results? This question on the Parse support site has a great answer from Héctor Ramos on how to return all the rows in a table with a PFQuery. Although.. as great as the answer is, it only really points you in the right direction. And does not supply a final solution to fetch every result using PFQuery.
I came up with a little sollution using a recursive block, which will use a PFQuery object to query Parse until every result has been returned.
+ (void)findAllObjectsWithQuery:(PFQuery *)query withBlock:(void (^)(NSArray *objects, NSError *error))block
{
__block NSMutableArray *allObjects = [NSMutableArray array];
__block NSUInteger limit = 1000;
__block NSUInteger skip = 0;
typedef void (^FetchNextPage)(void);
FetchNextPage __weak __block weakPointer;
FetchNextPage strongBlock = ^(void)
{
[query setLimit: limit];
[query setSkip: skip];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error)
{
// The find succeeded. Add the returned objects to allObjects
[allObjects addObjectsFromArray:objects];
if (objects.count == limit) {
// There might be more objects in the table. Update the skip value and execute the query again.
skip += limit;
[query setSkip: skip];
// Go get more results
weakPointer();
}
else
{
// We are done so return the objects
block(allObjects, nil);
}
}
else
{
block(nil,error);
}
}];
};
weakPointer = strongBlock;
strongBlock();
}
So to use this method we can simply do the following:
PFQuery *query = [PFQuery queryWithClassName:@"myClassName"];
[ParseProxy findAllObjectsWithQuery:query withBlock:^(NSArray *objects, NSError *error) {
if(!error)
{
NSLog(@"Loaded All Objects: %@",objects);
}
}];
Easy!