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:
PFQueryTableViewController
is shown, I'd like it to always get data from the local datastore How do I achieve this?
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.
I find it best, for now, to override the loadObjects function, which is called every time the tableView is refreshed. Just reload objects of the query into local datastore before loadObjects(0, clear: true)(Which handles refresh behaviors and hard to override) is called. (This should work fine with internet connection, or after refresh all the objects will be void. You need to add some of your own logic for perfection.)
var firstTime : Bool = true
//MARK: Query
func basicQuery() -> PFQuery {
let query = PFQuery(className: "CLASSNAME")
return query.orderByAscending("params")
}
override func queryForTable() -> PFQuery {
return basicQuery().fromLocalDatastore()
}
//MARK: - Refresh
//TODO: Should consider the condition with no internet connection
override func loadObjects() -> BFTask {
if firstTime {
// Load frome local data store
firstTime = false
return loadObjects(0, clear: true)
}
return queryForTable().findObjectsInBackground().continueWithBlock({ (task : BFTask!) -> AnyObject! in
if task.error != nil { // No object in local data store
return nil
}
if let objects = task.result as? [PFObject] { // Unpin local datastore objects
return PFObject.unpinAllInBackground(objects, withName: "cacheString")
}
return nil
}).continueWithSuccessBlock({ (task : BFTask!) -> AnyObject! in
// Fetch objects from Parse
return self.basicQuery().findObjectsInBackground()
}).continueWithSuccessBlock({ (task : BFTask!) -> AnyObject! in
if let objects = task.result as? [PFObject] {
return PFObject.pinAllInBackground(objects, withName: "cacheString")
}
return nil
}).continueWithSuccessBlock({ (task : BFTask!) -> AnyObject! in
return self.loadObjects(0, clear: true)
})
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.