Parse.com PFQueryTableViewController 本地数据存储

Posted

技术标签:

【中文标题】Parse.com PFQueryTableViewController 本地数据存储【英文标题】:Parse.com PFQueryTableViewController Local datastore 【发布时间】:2014-12-23 09:07:01 【问题描述】:

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

这是我想做的:

    当显示 PFQueryTableViewController 时,我希望它始终从本地数据存储中获取数据 但是,在视图呈现无延迟后(因为本地数据存储正在为数据源提供动力),我想进行异步调用以使用来自云的最新数据更新本地数据存储。此时,如果有新数据,我希望最新的数据能够无缝地出现在表格中,并且最好带有行动画。

我如何实现这一目标?

【问题讨论】:

我也在为此苦苦挣扎,似乎这可以揭示一些启示github.com/ParsePlatform/ParseUI-ios/issues/53 【参考方案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 中,响应拉动刷新事件(这就是我在其中有UIRefreshControl 代码的原因)或其他任何时候合适。

【讨论】:

我收到一条错误消息,说 bftask 是前向声明?【参考方案2】:

我发现现在最好覆盖 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)
    )

【讨论】:

以上是关于Parse.com PFQueryTableViewController 本地数据存储的主要内容,如果未能解决你的问题,请参考以下文章

parse.com - 如何使用 PHP SDK 从 parse.com 查询和获取类似数组的 json?

安卓 | Parse.com - 导入 Parse-UI

Parse.com 禁用推送通知通知

Parse.com 错误 3840

parse.com 上的 Apple 推送通知

Parse.com 云代码失败