1

i am newbie here in iOS and Parse Framework i want to fetch data from my Parse table from PFQuery like as

NSUInteger limit = 1500;
PFQuery *query = [PFQuery queryWithClassName:@"MapInfo"];
[query setLimit: limit];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
    if (!error) {
        NSLog(@"Successfully retrieved: %@", objects);
    } else {
        NSString *errorString = [[error userInfo] objectForKey:@"error"];
        NSLog(@"Error: %@", errorString);
    }
}];

it is Working as i want but it is give me only 1000 objects i want here to fetch all my table data it contain unto 2000 object and it will increment as day by day please help me for this.

For this Now i write a code like this but it is Only Give me 1000 Objects only

 NSMutableArray *allObjects = [NSMutableArray array];
NSUInteger limit = 0;
__block NSUInteger skip = 0;
PFQuery *query = [PFQuery queryWithClassName:@"MapInfo"];
[query setLimit: limit];
[query setSkip: skip];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (!error) {
        [allObjects addObjectsFromArray:objects];
        if (objects.count == limit) {

            skip += limit;
            [query setSkip: skip];
            [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
                NSLog(@"Array %@",objects);
            }];
             }

             } else {
                 NSLog(@"Error: %@ %@", error, [error userInfo]);
             }
             }];

thanks.

2
  • [query setLimit: 1000]; [query setSkip: 1000]; remove this line may work... Commented Feb 25, 2015 at 6:51
  • You can't do a query that retrieves more than 1000 objects. It's just parse standard. It's also for good reason and memory management. You don't want to load over 2000 objects at once, especially in a tableView. So your 1500 limit won't do anything. You have to skip through the first 1000 objects and get your next. Commented Feb 25, 2015 at 17:45

3 Answers 3

2

I believe there is a query limit on the number of objects that can be fetched. What I would do is query make two queries for the same thing but for the second query, do something like this

[query setSkip1000];

you can skip the first 1000 objects in the first query and grab the next 1000. Make your array an NSMutableArray and inside each block do this

[self.myArray addObjects:objects]; instead of self.myArray = objects; that way you are overwriting the objects in your array.

Edit

Instead of 2 separate queries you can also do this

NSMutableArray *allObjectsArray = [NSMutableArray array];
//Set this to the amount of objects you want. Has to be be 1000 or less
NSUInteger limit = 0;

//Set this to the amount you want to skip (Usually 0)
NSUInteger skip = 0;
PFQuery *query = [PFQuery queryWithClassName:@"tempClass"];
[query setLimit: limit];
[query setSkip: skip];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
  if (!error) {
    // The find succeeded. Add the returned objects to allObjects
    [allObjectsArray addObjectsFromArray:objects];
    if (objects.count == limit) {
      // There could be more objects in your database. Update the skip number and perform the same query.
      skip = skip + limit;
      [query setSkip: skip];
      [query findObject...// Exactly the same way as you did before to get the rest of your objects in the database
    }

  } else {
    // Log details of the failure
    NSLog(@"Error: %@ %@", error, [error userInfo]);
  }
}];
Sign up to request clarification or add additional context in comments.

8 Comments

Better answer, almost right! but your answer implies they need 2 seperate quereies but you can create a query in a query after the skip amount has been reached just update it so it doesn't imply one thing over the other. See the link in vampire walks answer for reference.
Ah I never seen anything like that. Is that a while loop? I have never used one of those in obj-c.
It has an example how to include a query within a query...the while loop is unnecessary
I see now. So I really was almost right. They just had the query inside the query. And check to see if the limit was reached. It makes sense and I was so close lol
|
2

This is a simple recursive solution to retrieve all the objects from a class using blocks.

Here is how you initially call it.

[self queryAllObjectswithLimit:1000 withSkip:0 withObjects:@[] withSuccess:^(NSArray * objects) {
    //All the objects
} failure:^(NSError * error) {
    //
}];

Here is the method.

- (void)queryAllObjectswithLimit:(NSUInteger )limit withSkip:(NSUInteger )skip withObjects:(NSArray *)objects withSuccess:(void (^)(NSArray *objects))success failure:(void (^)(NSError *error))failure {
//Store all the Objects through each layer of recurrsion
NSMutableArray *allObjects = [NSMutableArray arrayWithArray:objects];
PFQuery *query = [PFQuery queryWithClassName:@"Class_Name"];
query.limit = limit;
query.skip = skip;
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
    if (!error) {
        // The find succeeded. Add the returned objects to allObjects
        [allObjects addObjectsFromArray:objects];
        if (objects.count == limit) {
            //Recursively Call this until count does not equal limit, then begin returning all the objects back up
            [self queryAllObjectswithLimit:limit withSkip:skip+limit withObjects:allObjects withSuccess:^(NSArray * objects) {
                //This will return everything
                success(objects);
            } failure:^(NSError * error) {
                failure(error);
            }];
        } else {
            success(allObjects);
        }
    } else {
        failure(error);
    }
}];

}

I've tested this with less than 1000 objects, 1000 objects, and more than 1000 objects and it works perfectly.

Be cautious of how many objects you're grabbing though because this will grab all of them and if you're working with a large data set that might be an issue in terms of memory very quickly.

Comments

-2

https://parse.com/questions/fetch-all-data-in-a-table-using-pfquery

You can use the skip and limit parameter to paginate through all objects in the table by adding the value of limit to skip until the query returns an amount of objects that is less than limit.

NSMutableArray *allObjects = [NSMutableArray array];
NSUInteger limit = 0;
__block NSUInteger skip = 0;
PFQuery *query = [PFQuery queryWithClassName:@"MapInfo"];
[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];
      [query findObjects... // Execute the query until all objects have been returned. Keep adding the results to the allObjects mutable array.

    }
  } else {
    // Log details of the failure
    NSLog(@"Error: %@ %@", error, [error userInfo]);
  }
}];

8 Comments

it is not giving me as expectd result.
Change limit to 1000?
Beware, the sample code just shows you a basic idea, you have to modify it to feed your need.
it give me error in skip += limit error is Variable is not assignable (missing __block type specifier)
add __block in front of NSUInteger skip = 0; this makes skip assignable in block.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.