16

我正在使用 CRUD 功能构建一个简单的联系人目录,并且我想要离线编辑功能。我的联系人数据库将存储在 Parse.com 后端。这是否可以使用 Parse 缓存功能,或者我使用 Core Data 会更好吗?

4

3 回答 3

21

不,它不能。Parse 只是缓存查询的结果。这是极其有限的,并且与缓存所有 PFObject 不同。例如,假设您对所有“联系人”PFObject 运行查询。您可以对缓存做的唯一事情是稍后再次运行完全相同的查询(并获得完全相同的结果)。您甚至无法查询该缓存数据的子集。

另一个问题是用户对 PFObject 所做的任何更改都不会更新缓存的对象。例如,假设用户正在离线编辑联系人,并且您的代码正在调用saveEventually以尽可能将这些更改保存到 Parse。当您获得缓存的查询结果时,用户的更改不会反映在您的 PFObjects 中。我相信删除和添加的 PFObjects 也是如此。这将使离线使用变得很糟糕。以下是 Parse 论坛中涉及此主题的主题:

https://www.parse.com/questions/does-saving-an-object-supposed-to-update-the-local-cache-of-a-query-on-these-objects

我看到 Parse 开发人员提到将来某个时候会改进 Parse 对象的缓存。但是,此功能尚不存在,也不知道何时会出现。同时,如果你想支持离线使用,你必须使用 Core Data 或其他一些本地存储。FTASync(我从未使用过)旨在将 Parse 对象与 Core Data 同步:

https://github.com/itsniper/FTASync

您还可以编写自己的代码来同步两组数据。

于 2013-10-14T17:18:16.690 回答
6

Parse iOS/OSX SDK 提供了一个本地数据存储,可用于存储和检索 PFObject,即使网络不可用。要启用此功能,请在调用 setApplicationId:clientKey: 之前添加 libsqlite3.dylib 并调用 [Parse enableLocalDatastore]。

解析文档中所述

您可以通过固定 PFObject 将其存储在本地数据存储中。固定 PFObject 是递归的,就像保存一样,因此您要固定的对象指向的任何对象也将被固定。当一个对象被固定时,每次你通过获取或保存新数据来更新它时,本地数据存储中的副本都会自动更新。你根本不需要担心它。

PFObject *gameScore = [PFObject objectWithClassName:@"GameScore"];
gameScore[@"score"] = 1337;
gameScore[@"playerName"] = @"Sean Plott";
gameScore[@"cheatMode"] = @NO;
[gameScore pinInBackground];

如果您有多个对象,您可以使用 pinAllInBackground 便捷方法一次将它们全部固定。

[PFObject pinAllInBackground:listOfObjects];

从本地数据存储中检索对象就像通过网络检索对象一样。唯一的区别是调用 fromLocalDatastore 方法来告诉 PFQuery 在哪里寻找它的结果。

PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query fromLocalDatastore];
[[query getObjectInBackgroundWithId:@"xWMyZ4YE"] continueWithBlock:^id(BFTask *task) {
  if (task.error) {
    // Something went wrong.
    return task;
  }

  // task.result will be your game score
  return task;
}];

任何 PFQuery 都可以与本地数据存储一起使用,就像与网络一起使用一样。结果将包括您固定的与查询匹配的任何对象。评估查询时将考虑您对对象所做的任何未保存的更改。因此,您可以找到匹配的本地对象,即使该特定查询从未从服务器返回。

PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query fromLocalDatastore];
[query whereKey:@"playerName" equalTo:@"Joe Bob"];
[[query findObjectsInBackground] continueWithBlock:^id(BFTask *task) {
  if (task.error) {
    NSLog(@"Error: %@", task.error);
    return task;
  }

  NSLog(@"Retrieved %d", task.result.count);
  return task;
}];

当您完成一个对象并且不再需要它在本地数据存储中时,您可以简单地取消固定它。

[gameScore unpinInBackground];

还有一种方法可以一次取消固定多个对象。

[PFObject unpinAllInBackground:listOfObjects];

有关使用 Parse 的本地数据存储的更多信息,请查看 parse 网站上为 iOS/OSX 提供的本地数据存储文档。

于 2014-12-31T14:21:52.380 回答
1

不,它不能。我建议https://github.com/itsniper/FTASync

于 2015-01-22T19:32:48.793 回答