Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I populate a UITableView with data from a parse.com query after it is done running in the background?

I have a UITableViewController that is in charge of displaying a table full of employees. This data is being stored on a database on parse.com.

This is my UITableViewController, in which I just initiate the store:

-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    self = [super initWithNibName:nil bundle:nil];
    if(self){
        store = [[EmployeeStore alloc] init]; 
    }
    return self;
}

This is the EmployeeStore init method, in which i query for the employees:

-(id) init{
    self = [super init];
    if(self){
        employees = [[NSMutableArray alloc] init];
        [self fetchEmployeesFromDatabase];
    }
    return self;
}

fetchEmployeesFromDatabase, where I query for the employees.

-(void) fetchEmployeesFromDatabase{
    PFQuery *query = [PFQuery queryWithClassName:@"Employee"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            // The find succeeded.
            NSLog(@"Successfully retrieved %d scores.", objects.count);
            // Do something with the found objects
            for (PFObject *object in objects) {
                NSLog(@"%@", object.objectId);
                [employees addObject:object]; 
            }
        } else {
            // Log details of the failure
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
    }];
}

I am successfully receiving them, however the problem is the query takes place in the background, and does not finish until after the table view is done loading, so the table view does not populate. I need to have the table reload its data after the query is complete but how do I go about doing this?

like image 415
Sam D20 Avatar asked Jun 27 '13 06:06

Sam D20


2 Answers

UITableViewController

-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    self = [super initWithNibName:nil bundle:nil];
    if(self){
        store = [[EmployeeStore alloc] init];
        store.tableView = self.tableView; 
    }
    return self;
}

EmployeeStore.h

@property (nonatomic, strong) UITableView *tableView;

EmployeeStore.m

-(id) init{
    self = [super init];
    if(self){
        employees = [[NSMutableArray alloc] init];
        [self fetchEmployeesFromDatabase];
    }
    return self;
}

and fetchEmployeesFromDatabase

-(void) fetchEmployeesFromDatabase{
    PFQuery *query = [PFQuery queryWithClassName:@"Employee"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            // The find succeeded.
            NSLog(@"Successfully retrieved %d scores.", objects.count);
            // Do something with the found objects
            for (PFObject *object in objects) {
                NSLog(@"%@", object.objectId);
                [employees addObject:object]; 
            }

             dispatch_async(dispatch_get_main_queue(), ^ {
                [self.tableView reloadData];
              });

        } else {
            // Log details of the failure
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
    }];
}
like image 115
iCoder Avatar answered Oct 11 '22 06:10

iCoder


When the load completes tell the table view to reload.

if (!error) {
    // The find succeeded.
    NSLog(@"Successfully retrieved %d scores.", objects.count);
    // Do something with the found objects
    for (PFObject *object in objects) {
        NSLog(@"%@", object.objectId);
        [employees addObject:object]; 
    }

    dispatch_async(dispatch_get_main_queue(), ^ {
        [tableView reloadData];
    });
} else {

You need to ensure that your employees store is thread safe or is not accessed by the background and main threads concurrently.

like image 28
Gary Avatar answered Oct 11 '22 05:10

Gary