【问题标题】:RestKit + CoreData : How to save an object locally only after the remote save is successful?RestKit + CoreData:只有远程保存成功后,如何在本地保存对象?
【发布时间】:2012-06-13 00:45:11
【问题描述】:

我在 iOS 5.0 部署目标上使用带有 Core Data 的 RestKit 0.10.1 来构建一个与自定义 RESTFul API 接口的应用程序。由于离线连接很重要,我在设备上的本地 CoreData 数据库中维护用户数据的缓存。

现在,RestKit 非常棒,设置 RKFetchResultsTableController 以轻松显示和保存我的数据相当轻松。但是,RestKit 的一种行为似乎并不理想,我不知道如何更改。

我有一个名为“录音”的模型。要创建新的录音,我正在执行以下操作:

 Recording *r = [NSEntityDescription insertNewObjectForEntityForName:@"Recording" inManagedObjectContext:[[RKObjectManager sharedManager].objectStore managedObjectContextForCurrentThread]];

 r.name = newName; 

[[RKObjectManager sharedManager] sendObject:r toResourcePath:@"/recordings" usingBlock:^(RKObjectLoader *loader){
        loader.delegate = self; 
        loader.method = RKRequestMethodPOST;
        loader.serializationMIMEType = RKMIMETypeJSON;  

        loader.serializationMapping = [RKObjectMapping serializationMappingUsingBlock:^(RKObjectMapping *serializationMapping){
            [serializationMapping mapAttributes:@"name", nil];

        }];

        RBMappingProvider *mappings = (RBMappingProvider *)[[RKObjectManager sharedManager] mappingProvider];
        loader.objectMapping = [mappings recordingObjectMapping];

    }];

这将创建一个“记录”类型的新实体,然后在 POST 请求中将该实体发送到服务器。在成功的情况下,这很有效。

但是,问题是服务器有时会合法地拒绝这些创建。我在这些情况下发现,Core Data 数据库中已经有一个实体的本地副本,其 id 为 0(id 是服务器设置的主键)。

删除本地实体的唯一方法是强制从服务器刷新本地数据。

有没有办法只在服务器响应 2xx 后才在本地保存对象?或者,如果服务器响应的不是 2xx,是否有办法撤消更改?

谢谢,

【问题讨论】:

  • FWIW,按照 RestKit 文档中的规定创建具有 Recording *r = [Recording object] 的实体根本不会改变行为。
  • 你在RK中没有服务器响应的回调方法吗?保留对该对象的引用,如果上传被拒绝,则将其删除。
  • @mundi 这是一种方法,甚至可能是更理想的方法。但是,我想知道是否可以仅在服务器接受有效负载后才保留本地状态。这将导致更少的冗余代码。

标签: ios core-data restkit


【解决方案1】:

不幸的是,因为 Recording 是一个 NSManagedObject,即使是你的临时实例也需要插入到托管对象上下文中。 @Mundi 的维护引用并在错误发生后从上下文中删除它的解决方案是我将使用的解决方案。一些额外的代码胜过服务器的完全刷新。

升级到 0.20.x 将使这更容易。发送请求时使用的成功和失败块可以很容易地保留此引用并在失败时将其删除。例如:

[_objectManager postObject:aMessage
                      path:@"message"
                parameters:parameters
                   success:^(RKObjectRequestOperation * operation, RKMappingResult * mappingResult){
                     // Success code here
                   }
                   failure:^(RKObjectRequestOperation * operation, NSError * error){
                     [_managedObjectContext deleteObject:aMessage];
                     [_managedObjectContext save:nil];
                   }];

【讨论】:

    猜你喜欢
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多