Ios Parse.com PFQueryTableViewController本地数据存储

Ios Parse.com PFQueryTableViewController本地数据存储,ios,uitableview,swift,parse-platform,ios8,Ios,Uitableview,Swift,Parse Platform,Ios8,我有一个Swift应用程序,其中有一个PFQueryTableViewController,我想使用本地数据存储和Parse。但是,我对使用本地数据存储和实时查询感到困惑 以下是我想做的: 当显示PFQueryTableViewController时,我希望它总是从本地数据存储中获取数据 但是,在视图没有延迟地呈现之后(因为本地数据存储正在为数据源供电),我想进行一个异步调用,用来自云的最新数据更新本地数据存储。此时,如果有新的数据,我希望最新的数据无缝地显示在表中,最好使用行动画 我如何做到这

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

以下是我想做的:

  • 当显示
    PFQueryTableViewController
    时,我希望它总是从本地数据存储中获取数据
  • 但是,在视图没有延迟地呈现之后(因为本地数据存储正在为数据源供电),我想进行一个异步调用,用来自云的最新数据更新本地数据存储。此时,如果有新的数据,我希望最新的数据无缝地显示在表中,最好使用行动画

  • 我如何做到这一点

    以下是我是如何做到这一点的——也许这会让你走上正轨。如果你已经解决了这个问题,我很想看看你的解决方案

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

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

    我们可以在任何时候调用它:在
    viewDidLoad
    viewDidAppear
    中,响应pull-to-refresh事件(这就是为什么我在其中有
    UIRefreshControl
    代码),或者在其他合适的时候调用它。

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


    我也在努力解决这个问题,如果你感兴趣的话,这可能会给@Rama带来一些启示,如果你想看的话,我会为这个问题拼凑一个快速修复方法。我得到一个错误,说bftask是一个转发声明?
    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)
        })
    }