我正在使用 CRUD 功能构建一个简单的联系人目录,并且我想要离线编辑功能。我的联系人数据库将存储在 Parse.com 后端。这是否可以使用 Parse 缓存功能,或者我使用 Core Data 会更好吗?
3 回答
不,它不能。Parse 只是缓存查询的结果。这是极其有限的,并且与缓存所有 PFObject 不同。例如,假设您对所有“联系人”PFObject 运行查询。您可以对缓存做的唯一事情是稍后再次运行完全相同的查询(并获得完全相同的结果)。您甚至无法查询该缓存数据的子集。
另一个问题是用户对 PFObject 所做的任何更改都不会更新缓存的对象。例如,假设用户正在离线编辑联系人,并且您的代码正在调用saveEventually
以尽可能将这些更改保存到 Parse。当您获得缓存的查询结果时,用户的更改不会反映在您的 PFObjects 中。我相信删除和添加的 PFObjects 也是如此。这将使离线使用变得很糟糕。以下是 Parse 论坛中涉及此主题的主题:
我看到 Parse 开发人员提到将来某个时候会改进 Parse 对象的缓存。但是,此功能尚不存在,也不知道何时会出现。同时,如果你想支持离线使用,你必须使用 Core Data 或其他一些本地存储。FTASync(我从未使用过)旨在将 Parse 对象与 Core Data 同步:
https://github.com/itsniper/FTASync
您还可以编写自己的代码来同步两组数据。
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 提供的本地数据存储文档。
不,它不能。我建议https://github.com/itsniper/FTASync