使用嵌套数据更新 CoreData 对象时,RestKit 验证失败(Cocoa 错误 1550)

Posted

技术标签:

【中文标题】使用嵌套数据更新 CoreData 对象时,RestKit 验证失败(Cocoa 错误 1550)【英文标题】:RestKit validation failing when updating CoreData object with nested data (Cocoa error 1550) 【发布时间】:2014-09-03 20:28:50 【问题描述】:

我正在编写一个单元测试来检查我的 CoreData 对象是否正确更新。问题是,当我尝试使用具有地址的数据更新没有地址的项目时,我收到验证错误。当项目已经有地址时,一切都按预期工作,我已经标记了添加地址并通过测试的代码

我的模型结构如下:

[Project]
    -localId [int]
    -serverId [int]
    -name [string]
    -address [Address]

[Address]
    -lineOne [string]
    -lineTwo [string]
    -city [string]
    -state [string]
    -country [string]
    -zip [string]
    -project [Project]

Project 和 Address 在 CoreData 中具有一对一的关系,并且所有属性和关系都标记为可选。我在 RestKit 中使用 serverId 和 lineOne 作为标识。

这是有问题的单元测试:

// Create an object to match our criteria
Project *project = [NSEntityDescription insertNewObjectForEntityForName:@"Project" inManagedObjectContext:[RKManagedObjectStore defaultStore].persistentStoreManagedObjectContext];
[project setValue:@(1) forKey:@"serverId"];

//----IF I ADD THESE TWO LINES THE TEST PASSES----
//Address *address = [NSEntityDescription insertNewObjectForEntityForName:@"Address" inManagedObjectContext:[RKManagedObjectStore defaultStore].persistentStoreManagedObjectContext];
//[project setValue:address forKey:@"address"];



NSDictionary* fakeJson = @@"id" : @1, @"name" : @"TEST", @"address" : @@"line_1":@"123 Apple Street",@"line_2":@"Apartment 4",@"city":@"New York",@"country":@"USA",@"state":@"New York",@"zip":@"12345";

RKMappingTest* idTest = [RKMappingTest testForMapping:[Project showResponseMapping] sourceObject:fakeJson destinationObject:nil];
[idTest setManagedObjectContext:[RKManagedObjectStore defaultStore].persistentStoreManagedObjectContext];
[idTest performMapping];

//Assert that the destinationObject for the mapping is the existing one
XCTAssertEqualObjects(project, idTest.destinationObject, @"Expected to match the project, but did not");

这是抛出的错误:

2014-09-03 16:14:28.599 TestProject[3692:607] E restkit.object_mapping:RKMappingOperation.m:342 Validation failed while mapping attribute at key path 'address' to value <Address: 0x115b57a0> (entity: Address; id: 0x115b1e20 <x-coredata:///Address/t5016F936-C646-4CD0-84EC-366D2A8C7F056> ; data: 
city = "New York";
country = USA;
lineOne = "123 Apple Street";
lineTwo = "Apartment 4";
localId = nil;
project = nil;
state = "New York";
zip = 12345;
). Error: The operation couldn’t be completed. (Cocoa error 1550.)
2014-09-03 16:14:28.600 Closeout[3692:607] E restkit:RKLog.m:151 Validation Error
                    NSLocalizedDescriptionKey:      The operation couldn’t be completed. (Cocoa error 1550.)
                    NSValidationKeyErrorKey:            address
                    NSValidationPredicateErrorKey:  (null)
                    NSValidationObjectErrorKey:
<Project: 0x115a4e50> (entity: Project; id: 0x115aa980 <x-coredata:///Project/t5016F936-C646-4CD0-84EC-366D2A8C7F055> ; data: 
address = nil;
localId = nil;
name = TEST;
serverId = 1;
)

由于如果我向初始 CoreData 对象添加空白地址,则测试通过,因此问题不在于映射或地址数据无效。我还可以从日志中看出新的 Address 对象正在正确创建,只是无法通过关系链接它们。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

整整两天挠头后解决了这个问题。问题是当您在新项目上选中“使用 CoreData”框时,Xcode 生成的 AppDelegate 中的代码。它创建了一个 CoreData 堆栈,然后我们创建了自己的单元测试堆栈,当 RestKit 将数据拉下时,它试图连接来自不同上下文的对象(即使我们在每个操作中指定了一个上下文)。删除 AppDelegate 中所有 CoreData 生成的代码解决了这个问题。

【讨论】:

【参考方案2】:

很难诊断,因为我们没有您的 Core Data 架构定义,但是会抛出 NSValidationErrors,因为您有某种要求,即 Project 对象必须具有地址对象。在访问数据之前,您是否有某种必须满足的关系?具体来说,检查器中是否未选中 Optional 复选框?请参阅随附的屏幕截图:

【讨论】:

我只是仔细检查了两个实体上的关系和所有其他属性,它们都被标记为可选。我读到当有问题的对象处于不同的上下文中时,通常会抛出 Cocoa Error 1550,但我也检查了这一点,这似乎不是问题。我只有一个我曾经使用过的上下文。

以上是关于使用嵌套数据更新 CoreData 对象时,RestKit 验证失败(Cocoa 错误 1550)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 RestKit 将嵌套的 JSON 对象存储到核心数据中

Spring JPA 更新不适用于嵌套对象

对 CoreData 执行添加/更新时出现问题

识别 iCloud coreData 更新:良好实践

CoreData 获取嵌套对象

处理来自服务器的 JSON 数据并添加/更新 CoreData 中的对象