Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse.com PFQueryTableViewController Local datastore

I have a Swift app in which I have a PFQueryTableViewController, and I'd like to use the local datastore with Parse. But, I'm getting confused about using the local datastore alongside live queries.

Here is what I'd like to do:

  1. When the PFQueryTableViewController is shown, I'd like it to always get data from the local datastore
  2. But, after the view is rendered with no lag (since the local data store is powering the source of the data), I want to make an asynchronous call to update the local data store with most updated data from the cloud. At this point, if there is new data, I'd like the most updated data to appear in the table seamlessly and preferably with row animation.

How do I achieve this?

like image 282
John Doe Avatar asked Dec 23 '14 09:12

John Doe


1 Answers

Here's how I managed this - maybe it will put you on the right track. I'd be interested to see your solution if you have already fixed the problem.

First, I made a convenience method to create my base query:

- (PFQuery *)baseQuery
{
    PFQuery *query = [PFQuery queryWithClassName:@"MyClass"];
    [query orderByDescending:@"myParameter"];
    return query;
}

We want queryForTable to hit the local datastore consistently.

- (PFQuery *)queryForTable
{
    return [[self baseQuery] fromLocalDatastore];
}

So now all that's left to do is populate the local datastore from the network:

- (void)refreshObjects
{
    [[[self baseQuery] findObjectsInBackground] continueWithBlock:^id(BFTask *task) {
        if (task.error) {
            [self.refreshControl endRefreshing];
            return nil;
        }
        return [[PFObject unpinAllObjectsInBackgroundWithName:@"cacheLabel"] continueWithSuccessBlock:^id(BFTask *unused) {
            NSArray *objects = task.result;
            return [[PFObject pinAllInBackground:objects withName:@"cacheLabel"] continueWithSuccessBlock:^id(BFTask *unused) {
                [self.refreshControl endRefreshing];
                [self loadObjects];
                return nil;
            }];
        }];
    }];
}

We can call this whenever we want: in viewDidLoad or viewDidAppear, in response to a pull-to-refresh event (which is why I have the UIRefreshControl code in there) or whenever else it might be appropriate.

like image 179
David Schwartz Avatar answered Nov 10 '22 09:11

David Schwartz