用新的核心数据初始化 RestKit 的 RKPaginator
Posted
技术标签:
【中文标题】用新的核心数据初始化 RestKit 的 RKPaginator【英文标题】:Initializing RestKit's RKPaginator with fresh core-data 【发布时间】:2013-12-20 12:21:30 【问题描述】:我有一个RKPaginator
,它从服务器加载数据并将其保存到Core Data。加载和分页时,这一切都像魅力一样。但是,Core Data 中的项目是持久的,所以每当我重新进入 viewcontroller 或重新启动应用程序时,所有以前的分页数据仍然在 Core Data 中。
我想在启动应用程序时从一张白纸开始。如何告诉 Core Data 刷新其内容?我尝试了以下代码,但它似乎只能在某些时候工作,而且不规则,可能是来自传入数据的计时错误。我真的很想只在我的 Api-Request 成功回复时才刷新。
NSString *entityDescription = @"Activity";
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:weakSelf.managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *managedObject in items)
[self.managedObjectContext deleteObject:managedObject];
我将如何实现这一目标?
【问题讨论】:
你在那个代码之后保存了吗?您的实体是否有日期(例如下载日期)? 不,我没有保存。我会这样做的,谢谢。我在实体中也没有下载日期。这不是服务器提供给我的东西。从服务器获取数据后是否需要设置? 如果您想在收到回复后进行清除,您需要通过某种方式来区分什么是新的,什么是旧的...... 我可以记下进入 ViewContoller 的时间,任何旧的都被删除,而加载的任何东西都会获得一个新的当前时间戳。 你可以,但你必须重新处理所有映射的项目,然后重新保存数据库。不是问题,而是麻烦。 【参考方案1】:最简单的选择是在应用启动时从磁盘中删除 Core Data 存储文件并创建一个新文件。这显然不适用于在请求返回良好数据之前保留数据。
为此,您需要能够分辨什么是旧的,什么是新的。 RestKit 可以为您做到这一点,但如果您正在加载分页数据,它将无法正常工作(当您获得新页面时,它往往会删除您拥有的页面)。
您可以使用与您所拥有的代码类似的代码(应该可以),但在请求的 success
块中。在success
块中,您拥有所有新项目,因此您只需检查它是否是第一个请求(BOOL
实例变量),如果是,则删除不在mappingResult
中的所有内容。
【讨论】:
最后一个解决方案是我想要的。在新数据到达之前,旧数据应该是可见的。谢谢。【参考方案2】:我的情况非常相似,使用的是 RestKit 和 Core Data。远程数据始终是最新的源,因此我希望 Core Data “清除”远程数据库中不存在的内容。
我花了一段时间尝试做你想做的事 - 完全清除本地持久存储 - 我尝试的每一种方法似乎都会导致问题。
RestKit 具有内置功能,可以为您更新 CoreData 并删除 CoreData 中不再存在于远程数据源中的那些实体(或 API 不再为特定调用返回的实体)。
它被称为“获取请求块”。
- (void)setupFetchRequestBlocksForObjectManager:(RKObjectManager*)manager
[manager addFetchRequestBlock:^NSFetchRequest *(NSURL *URL)
RKPathMatcher *pathMatcher = [RKPathMatcher pathMatcherWithPattern:@"article"];
NSDictionary *argsDict = nil;
BOOL match = [pathMatcher matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:&argsDict];
if (match)
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Article"];
fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"articleId" ascending:YES] ];
return fetchRequest;
return nil;
];
在这个例子中,我描述了这个 Fetch Request Block 所针对的 API 调用,然后描述了应该匹配它的 CoreData 请求。任何与 API 调用返回的对象不同的 Core Data 对象都将被更改/删除。
这个例子是一个非常简单的 API 调用,但你也可以在匹配器中包含参数,以便它只匹配更复杂的请求 - there's a good example of that on the RestKit site.
还有一个关于 SO 的问题here.
【讨论】:
您是否在 RKPaginator 中使用此示例?加载第二页笔记会导致第一页的数据被删除吗? 我没有使用 RKPaginator,但我已经尝试使用分页 API 调用。您必须小心 NSFetchRequest 返回与您正在调用的 URL(包括参数)相同的页面 - 这是一个正确的“匹配”。链接中的示例在匹配请求的参数方面做得更多。这样做当然更复杂,但这就是这些 Fetch Request Blocks 的用途,希望对 RKPaginator 的支持会更好(如果它还没有 - 如果我错了,请纠正我)。 我设法从 Wain 那里得到了一个很好的例子,所以目前我会坚持下去。但是当我有更多时间时,我会尝试获取请求块,因为我想尽可能多地学习 RestKit 技术。当我走到那一步时,我会再次发布。感谢您的信息。以上是关于用新的核心数据初始化 RestKit 的 RKPaginator的主要内容,如果未能解决你的问题,请参考以下文章