Search code examples
iosparse-platformpfquery

Set PFQuery order


I want to make my PFQuery come in a random order, so the next time I'm creating the same PFQuery with limit it won't return the same objects as the first one.

PFQuery *query = [PFUser query];
[query orderBy...]; //Is there a randomOrder method?
                    //Or a workaround to get random order?
[query setLimit:10];

I need this to be in a random order every time, or else the PFQuery will contain the same 10 objects everytime


Solution

  • You can't change the ordering of data returned in the query, but you can use paging to change the first object that is returned - so you could do something like this (it is based on the ToDo sample code from Parse but it will work for any object) -

    PFQuery *query =[PFQuery queryWithClassName:@"Todo"];
    
    NSInteger count=[query countObjects];
    NSInteger skip = arc4random_uniform(count-10);
    
    query.skip=skip;
    query.limit=10;
    
    NSArray *results=[query findObjects];
    
    NSLog(@"object count=%d",results.count);
    
    for (PFObject *object in results) {
        NSLog(@"text=%@",object[@"text"]);
    }
    

    You can now retrieve your 10 objects. for any given skip count they will be in the same order, but you could randomise the order after you retrieved the 10 items. Simply put them into an NSMutableArray and use technique in this answer - Re-arrange NSArray/MSMutableArray in random order

    Note that this code isn't optimal as it doesn't perform the fetch tasks on the background thread. To use background threads you would use something like the following -

    PFQuery *query =[PFQuery queryWithClassName:@"Todo"];
    
    
    [query countObjectsInBackgroundWithBlock:^(int number, NSError *error) {
    
        query.skip=arc4random_uniform(number-10);;
        query.limit=10;
    
        [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            if (error) {
            NSLog(@"An error occurred - %@",error.localizedDescription);
            }
            else {
                NSLog(@"object count=%d",objects.count);
    
                for (PFObject *object in objects) {
                    NSLog(@"text=%@",object[@"text"]);
                }
            }
        }];
    
    
    }];