I have a problem with the object mapping from a JSON
string to a NSManagedObject
. I use RestKit
via getObject
request and the Core Data integration. And I want to automatically map the JSON response.
1.) I get from a webservice the following response ("A" object):
{
"Bs":[
{ "id" : "abc", "name" : "name 1"},
{ "id" : "def", "name" : "name 2"}
{ "id" : "abc", "name" : "name 1"},
],
"id": "1"
}
2.) This response has ordered values (B Objects), with sometimes the same object ("id" : "abc") more than one time. Further more, the order of the items is important.
3.)
Core-Data has not the support to save multiple relations to the same object, because it used a NSSet
(NSOrderedSet
). And it ignores all double objects.
Has anyone an idea how I could solve the problem?
My try, which fails:
1.) I insert a new core data table (AB), which:
- has a reference to A
- has a position field
- has a reference to one B, from the A
2.)
I try to map the object with a RKValueTransformer
instance.
This iterates over the JSON
response for the B instances and create AB objects with the current position. These objects are saved in an NSSet
, which return from the custom value transformer
RKValueTransformer *aabbTransformer = [RKBlockValueTransformer valueTransformerWithValidationBlock:^BOOL(__unsafe_unretained Class sourceClass, __unsafe_unretained Class destinationClass) {
return ([sourceClass isSubclassOfClass:[NSArray class]] && [destinationClass isSubclassOfClass:[NSOrderedSet class]]);
} transformationBlock:^BOOL(id inputValue, __autoreleasing id *outputValue, Class outputValueClass, NSError *__autoreleasing *error) {
// Validate the input and output
RKValueTransformerTestInputValueIsKindOfClass(inputValue, [NSArray class], error);
RKValueTransformerTestOutputValueClassIsSubclassOfClass(outputValueClass, [NSOrderedSet class], error);
NSMutableOrderedSet *outputSet = [[NSMutableOrderedSet alloc] init];
NSInteger pos = 1;
for (id b in inputValue) {
// see JSON output at the top
// B instance already exists in core data persistent store
NSString *bid = [b valueForKeyPath:@"id"];
B *b = [B bById:bid];
// create AB instance
AB *ab = [NSEntityDescription ...]
ab.b = b;
ab.position = [NSNumber numberWithInteger:pos];
[outputSet addObject:ab];
pos++;
}
// return for A.abs
*outputValue = [[NSOrderedSet alloc] initWithOrderedSet:outputSet];
return YES;
}];
RKAttributeMapping *aabbMapping = [RKAttributeMapping attributeMappingFromKeyPath:@"bs" toKeyPath:@"abs"];
aabbMapping.valueTransformer = aabbMappingTransformer;
3.) But I get an error: illegal attempt to establish a relationship 'abs' between objects in different contexts But I use always the same context.
If you don't have an better idea, do you have a solution for this problem?