RestKit + CoreData:只有在远程保存成功后才能在本地保存对象?

apu*_*rva 5 core-data ios restkit

我在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];

    }];
Run Code Online (Sandbox Code Playgroud)

这将创建一个类型为"Recording"的新实体,然后在POST请求中将实体发送到服务器.在成功案例中,这很有效.

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

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

有没有办法只在服务器响应2xx时本地持久保存对象?或者,有没有办法撤消更改,如果服务器响应除了2xx之外的任何东西?

谢谢,

dan*_*elM 0

不幸的是,因为 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];
                   }];
Run Code Online (Sandbox Code Playgroud)