【问题标题】:RestKit + CoreData: replace entity content in case of operation success, leave as it is in case of failureRestKit + CoreData:操作成功时替换实体内容,失败时保持原样
【发布时间】:2014-01-23 10:34:55
【问题描述】:

我在如下结构中实现了一个简单的 REST 请求:

RKManagedObjectRequestOperation *operation = [[RKManagedObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];
operation.targetObject = nil;
operation.savesToPersistentStore = YES;
operation.managedObjectContext = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;
operation.managedObjectCache = [RKManagedObjectStore defaultStore].managedObjectCache;

[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
    // Handle success   
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
    // Handle failure
}];

如何修改代码,以便:

  • 如果成功,我需要清空 DB 上的相关实体,并将其内容替换为来自 WS 的新实体(不更新,替换整个内容);
  • 如果发生故障,不应发生任何事情,并且 DB 上的实体必须保持原样。

为了删除数据库实体,在操作之前我会按照此处报告的方式进行操作: Core Data: Quickest way to delete all instances of an entity, 但无论 WS 答案是什么,这都会清空实体。

非常感谢任何帮助, 非常感谢, 丹

EDIT1:

按照@Wain 的建议,我在操作中添加了一个获取请求块,如下所示:

RKFetchRequestBlock fetchRequestBlock = ^NSFetchRequest *(NSURL *URL)
{
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"EntityToBeUpdated"];
    fetchRequest.sortDescriptors = @[ [NSSortDescriptor sortDescriptorWithKey:@"order" ascending:NO] ];
    return fetchRequest;
};

operation.fetchRequestBlocks = @[fetchRequestBlock];
operation.deletesOrphanedObjects = YES;

但结果没有改变:db 上的项目没有更新或删除。

【问题讨论】:

    标签: ios rest core-data restkit


    【解决方案1】:

    RestKit 是基于更新而不是替换。因此,您的要求在映射期间很难管理。你可以考虑:

    1. 让 RestKit 创建一个新实例并在成功块中删除旧实例 - 短时间内重复对象。
    2. 使用动态映射来检查响应,然后再开始映射以决定是否删除 - 有点 hacky。
    3. 让 JSON 响应包含所有键的值,这样所有内容都会被覆盖。

    从错误的角度来看,如果错误返回一个 HTTP 状态代码,并且您没有该代码的响应描述符,那么 RestKit 将不会改变任何内容。


    根据您在下面的评论,您实际上是在寻找孤立项目删除。这是使用获取请求块完成的。请参阅Fetch Request Blocks and Deleting Orphaned Objects here 部分。您不需要谓词,只需一个获取请求。

    【讨论】:

    • 嗨 Wain,WS 的回答如下:“items”:[{“id”:“1”,“type”:“type1”,“label”:“label1”, "order": "1" },{ "id" : "2", "type": "type2", "label": "label2", "order": "2" } ] 可以更改为:"items ": [{ "id" : "1", "type": "type5", "label": "label5", "order": "1" } ] 这意味着必须用新的值更新第一项,并且第二个删了。是否有可能或者我必须如上所述清空实体?
    • 感谢您对使用获取请求块的建议。为了使用它,我应该保留上面写的所有代码,只需添加 operation.fetchRequestBlocks = ... ?
    • 我会使用对象管理器而不是操作,它更容易并且提供更多功能。
    • 由于我不清楚如何按照建议使用对象管理器来实现这一点,因此我尝试添加一个 fetchRequestBlocks,请参阅上面代码中的 EDIT1,但没有任何改变..
    • 我假设实体名称是正确的。你真的不需要排序描述符。您是否添加了日志/断点来检查它是否被使用?您是否在之前、之后和更新时记录上下文内容?所有这些日志都显示了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2011-07-29
    相关资源
    最近更新 更多