ios - RestKit 发布嵌套托管对象会创建重复项

标签 ios core-data restkit relationship restkit-0.20

我在使用 RestKit 发布带有嵌套 NSManagedObjects 的 NSManagedObject 时遇到了一些困难。当 POST 返回时,我似乎得到了插入到 CoreData 中的子 NSManagedObjects 的重复记录。这是模型的快照:

Model

这是我发布的 JSON:

{
  "actions": [], 
  "application": "Identify", 
  "createBy": "welcomed", 
  "createDt": "2014-04-11T16:26:15Z", 
  "description": null, 
  "externalId": null, 
  "groupId": "5", 
  "id": 0, 
  "images": [
    {
      "format": "JPEG", 
      "height": 200, 
      "id": 0, 
      "image": "/9j/4A..../Pv5n/9k=", 
      "status": "C", 
      "type": "MUGSHOT", 
      "width": 200
    }
  ], 
  "locked": null, 
  "modifyBy": null, 
  "modifyDt": null, 
  "priv": null
}

这是在 POST 之后从服务返回的 JSON:

{
"actions": [], 
  "application": "Identify", 
  "createBy": "welcomed", 
  "createDt": 1397233575000, 
  "description": null, 
  "externalId": null, 
  "groupId": "5", 
  "id": 11, 
  "images": [
    {
      "captureDevice": null, 
      "createBy": null, 
      "createDt": null, 
      "format": "JPEG", 
      "height": 200, 
      "id": 11, 
      "image": "/9j/4AAQSkZJR.../Pv5n/9k=", 
      "recordId": 11, 
      "status": "C", 
      "type": "MUGSHOT", 
      "width": 200
    }
  ], 
  "locked": false, 
  "modifyBy": null, 
  "modifyDt": null, 
  "priv": false
}

编辑(我想这很重要):这是 WTSImage 和 WTSRecord 的映射:

RKEntityMapping *recordMapping = [RKEntityMapping mappingForEntityForName:@"WTSRecord" inManagedObjectStore:self.managedObjectStore];
    [recordMapping addAttributeMappingsFromDictionary:@{
                                                        @"id":@"dbId",
                                                        @"externalId":@"extId",
                                                        @"groupId":@"groupId",
                                                        @"application": @"application",
                                                        @"description": @"desc",
                                                        @"priv": @"priv",
                                                        @"locked": @"locked",
                                                        @"createBy": @"createBy",
                                                        @"createDt": @"createDt",
                                                        @"modifyBy": @"modifyBy",
                                                        @"modifyDt": @"modifyDt",
                                                        }];
    recordMapping.identificationAttributes = @[@"dbId"];

    //image mapping
    RKEntityMapping *imageMapping = [RKEntityMapping mappingForEntityForName:@"WTSImage" inManagedObjectStore:self.managedObjectStore];
    [imageMapping addAttributeMappingsFromDictionary:@{
                                                       @"id": @"dbId",
                                                       @"status": @"status",
                                                       @"type": @"type",
                                                       @"format": @"format",
                                                       @"width": @"width",
                                                       @"height": @"height",
                                                       @"image": @"base64Image"
                                                       }];

    imageMapping.identificationAttributes = @[@"dbId"];
    [recordMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"images" toKeyPath:@"images" withMapping:imageMapping]];

以下代码是我创建 NSManagedObjects 并调用 [RKObjectManager postObject:path:parameters:success:failure::

WTSRecord *record = [NSEntityDescription insertNewObjectForEntityForName:@"WTSRecord" inManagedObjectContext:self.managedObjectContext];
record.createBy = @"welcomed";
record.createDt = [NSDate date];
record.application = kWTSApplicationIdentify;
record.groupId = @"5";

WTSImage *image = [NSEntityDescription insertNewObjectForEntityForName:@"WTSImage" inManagedObjectContext:self.managedObjectContext];
image.height = [NSNumber numberWithFloat:mugshot.size.height];
image.width = [NSNumber numberWithFloat:mugshot.size.width];
image.imageData = UIImageJPEGRepresentation(imageData, 1.0);
image.type = kWTSCaptureTypeMugshot;
image.format = kWTSCaptureFormatJpeg;
image.status = kWTSCaptureStatusCaptured;

image.record = record;
[record addImagesObject:image];

RKObjectManager *manager = [RKObjectManager sharedManager];
[manager postObject:record path:@"records" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {

    } failure:^(RKObjectRequestOperation *operation, NSError *error) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error Sending Record" message:error.localizedDescription delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }];

调用成功 block 时,我检查了 sqlite 数据库,插入了 1 个 WTSRecord 和 2 个 WTSImage。其中一个 WTSImages 具有正确的 WTSRecord FK 和来自数据库的 PK,而另一个似乎是孤立的(dbId 和 WTSRecord 的 FK 未设置)。

这是 RestKit 和核心数据跟踪日志的链接:https://dl.dropboxusercontent.com/u/466390/restkit2.txt

希望有人能帮忙!谢谢!

编辑 经过更多搜索,我找到了这个页面:https://github.com/RestKit/RestKit/issues/1228

在将它们发布到 REST 服务之前,我是否必须使用 UUID 在客户端创建标识元素?如果不首先在客户端设置标识属性,RestKit 是否无法将请求对象映射回已在对象存储中创建的对象?

最佳答案

对于发布的对象,RestKit 了解如何使用响应数据更新该项目,但这不适用于关系内容。从技术上讲,它可以编码,但目前还没有。

如果您需要映射后关系中的对象与您创建的对象相同,那么您就有问题了。如果您不介意它是一个不同的对象,那么问题就是删除重复项...

重复删除:

处理 POST 响应时不使用获取请求 block ,因此您需要获取欺骗并手动删除它。我假设任何与记录没有关系的图像都是骗局,因此执行起来相对简单。

关于ios - RestKit 发布嵌套托管对象会创建重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23018541/

相关文章:

ios - 如何使用 RestKit 发送 bool 值?

ios - 访问 UICollectionView 的父 UIViewController

ios - CoreData - NSManagedObject 子类的好处

swift - 如何将核心数据加载到结构中

ios - 在 RestKit 中从 json 中的兄弟节点映射对象

ios - RestKit 映射字符串数组以发布到服务器

ios - 如何重新显示 IsLoaded 的 ViewController

ios - UILabel 将文本居中对齐

iPhone:将用户数据保存在 plist、SQLite 或 cookie 中?

ios - RestKit - 通过嵌套外键的核心数据多对多关系