Search code examples
ios7xcode5parse-platform

Parse.com query for 10000 (10K) objects


I have a parse database with a class named MeetingObject filled with 6000 objects (it will grow by the way...).

Being the parse query limit 1000 I'm trying to get them using the skip query property.

The following code gives me 2000 objects:

NSMutableArray *allObjects = [NSMutableArray array];
NSUInteger limit = 1000;
__block NSUInteger skip = 0;
[query setLimit: limit];
[query setSkip: skip];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (!error) {
        [allObjects addObjectsFromArray:objects];
        NSLog(@"%lu", (unsigned long)allObjects.count );

        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];
            [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
                [allObjects addObjectsFromArray:objects];
                NSLog(@"%lu", (unsigned long)allObjects.count );
            }];
        }

    }  else if (error || [error code] == kPFErrorConnectionFailed) {

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error!" message:NSLocalizedString(@"The Internet connection appears to be offline.",@"no internet") delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok", nil];
        self.navigationItem.rightBarButtonItem.enabled = YES;
        self.tableView.userInteractionEnabled = YES;
        [alertView show];
        return;
    }
}];

It is my understanding that if I want to get 1000 more objects I have to add another nested query, then another for the next 1000 and so on like this:

// finding the first 1000 objects
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (!error) {
        [allObjects addObjectsFromArray:objects];
        NSLog(@"%lu", (unsigned long)allObjects.count );

        if (objects.count == limit) {
            // finding another 1000 objects
            skip += limit;
            [query setSkip: skip];
            [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
                [allObjects addObjectsFromArray:objects];
                NSLog(@"%lu", (unsigned long)allObjects.count );

                if (objects.count == limit) {
                    // finding another 1000 objects
                    skip += limit;
                    [query setSkip: skip];
                    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
                        [allObjects addObjectsFromArray:objects];
                        NSLog(@"%lu", (unsigned long)allObjects.count );
                    }];
                }

            }];

        }

but what if I don't know the exact number of objects? I tried using:

while (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];
        [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            [allObjects addObjectsFromArray:objects];
            NSLog(@"%lu", (unsigned long)allObjects.count );
        }];
    }

but I get

* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This query has an outstanding network connection. You have to wait until it's done.'

because of course the queries are made before the last one is finished...


Solution

  • what I would do is to fetch the number of objects first, then query using skip method.

    PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
    [query whereKey:@"playername" equalTo:@"Sean Plott"];
    [query countObjectsInBackgroundWithBlock:^(int count, NSError *error) {
      if (!error) {
         dispatchFindObjectsUsingLimit(count)
      } else {
        // The request failed
      }
    }];