Parse.com PFQueryTableViewController本地数据存储区

时间:2014-12-23 09:07:02

标签: ios uitableview swift parse-platform ios8

我有一个Swift应用程序,其中有一个PFQueryTableViewController,我想将本地数据存储区与Parse一起使用。但是,我对使用本地数据存储区和实时查询感到困惑。

以下是我想做的事情:

  1. 显示PFQueryTableViewController时,我希望始终从本地数据存储中获取数据
  2. 但是,在视图呈现没有延迟之后(因为本地数据存储正在为数据源供电),我想进行异步调用以使用来自云的最新数据更新本地数据存储。此时,如果有新数据,我希望最新的数据无缝地显示在表格中,最好是行动画。
  3. 我如何实现这一目标?

2 个答案:

答案 0 :(得分:1)

这是我如何管理这个 - 也许它会让你走上正轨。如果您已经解决了问题,我有兴趣看看您的解决方案。

首先,我创建了一个方便的方法来创建我的基本查询:

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

我们希望queryForTable能够始终如一地点击本地数据存储区。

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

所以现在剩下要做的就是从网络填充本地数据存储区:

- (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;
            }];
        }];
    }];
}

我们可以随时调用此方法:在viewDidLoadviewDidAppear中,响应一个pull-to-refresh事件(这就是为什么我有UIRefreshControl代码)或者在任何其他地方它可能是合适的。

答案 1 :(得分:0)

我现在发现最好覆盖loadObjects函数,每次刷新tableView时都会调用它。在调用loadObjects(0,clear:true)(处理刷新行为并且难以覆盖)之前,只需将查询对象重新加载到本地数据存储区。 (这应该可以正常使用互联网连接,或者刷新后所有对象都将无效。您需要添加一些自己的完美逻辑。)

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)
    })
}