我正在构建一个带有CRUD功能的简单联系人目录,我想离线编辑功能。我的联系人数据库将存储在 Parse.com 后端。使用解析缓存功能是否可以做到这一点,还是使用核心数据
不,它不能。解析只是缓存查询的结果。这是非常有限的,与缓存所有 PFObject 不同。例如,假设您对所有"联系人"PFObjects运行了查询。您唯一能对缓存做的是稍后再次运行完全相同的查询(并获得完全相同的结果)。您甚至无法查询该缓存数据的子集。
另一个问题是缓存的对象不会使用用户对 PFObjects 所做的任何更改进行更新。例如,假设用户正在脱机编辑联系人,并且您的代码正在调用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(我从未使用过)旨在将解析对象与核心数据同步:
https://github.com/itsniper/FTASync
您还可以编写自己的代码来同步两组数据。
Parse iOS/OSX SDK 提供了一个本地数据存储,可用于存储和检索 PFObjects,即使网络不可用也是如此。要启用此功能,请添加 libsqlite3.dylib 并在调用 setApplicationId:clientKey: 之前调用 [Parse enableLocalDatastore]。
如解析文档中所述:
可以通过固定 PFObject 将其存储在本地数据存储中。寄托 PFObject 是递归的,就像保存一样,因此任何对象 由您要固定的那个指向的那个也将被固定。当一个 对象被固定,每次通过获取或保存新的对象进行更新时 数据,则本地数据存储中的副本将自动更新。 你根本不需要担心它。
PFObject *gameScore = [PFObject objectWithClassName:@"GameScore"]; gameScore[@"score"] = 1337; gameScore[@"playerName"] = @"Sean Plott"; gameScore[@"cheatMode"] = @NO; [gameScore pinInBackground];
如果您有多个对象,则可以使用 pinAllIn背景方便的方法。
[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 提供的本地数据存储文档。
不,它不能。我建议 https://github.com/itsniper/FTASync