5

我在 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,是否有办法撤消更改?

谢谢,

4

1 回答 1

0

Unfortunately, because Recording is an NSManagedObject, even your temporary instance needs to be inserted into the managed object context. @Mundi's solution of maintaining the reference and deleting it from the context after the error is the solution I would use. A bit of extra code beats a full refresh from the server.

Upgrading to 0.20.x will make this easier. The success and failure blocks that are used when sending a request make it very easy to keep this reference and delete it on failure. For example:

[_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];
                   }];
于 2013-10-18T17:15:28.073 回答