2
votes

See my other question for background: Will RestKit's dynamic mapping solve this complex JSON mapping?

Due to the way the server structures the json data that I need to convert into NSManagedObjects, I'm passing the parsed json to do a direct object mapping, like so:

RKObjectMapping *mapping = [RKObjectMapping requestMapping];
[mapping addAttributeMappingsFromDictionary:@{@"id": @"id", @"name": @"name"}];
NSDictionary *mappingsDictionary = @{ [NSNull null]: mapping };
RKMapperOperation *mapper = [[RKMapperOperation alloc]
        initWithRepresentation:dataArray mappingsDictionary:mappingsDictionary];
NSError *mappingError = nil;
BOOL isMapped = [mapper execute:&mappingError];
if (isMapped && !mappingError) {
    for (id thing in mapper.mappingResult.array) {
        NSLog(@"Mapped the '%@' thing: %@", NSStringFromClass([thing class]), thing);
    }
}

The NSMutableArray, dataArray, looks like this: [ {id: 1, "name":"AAA"}, {id: 2, "name":"BBB"}, ...]

And the code prints out a number of dictionaries, but what I want are Foo objects (.id & .name) generated from my data model class.

If I use:

RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Foo" inManagedObjectStore:store];

where the store is working well as it succeeds on 'normal' RestKit requests, I get the error:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: the entity (null) is not key value coding-compliant for the key "id".'

What am I doing wrong?

UPDATE:

Following Wain's advice, I added:

RKManagedObjectMappingOperationDataSource *mappingDS = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:store.mainQueueManagedObjectContext cache:store.managedObjectCache];
mappingDS.operationQueue = [NSOperationQueue new];

before the above code, and then, after creating the mapper, and before calling execute, I set the data source, as suggested:

mapper.mappingOperationDataSource = mappingDS;

And I get the expected NSManagedObjects.

1

1 Answers

2
votes

The mapper operation does not itself know how to create the instances of the class that you are mapping to. The entity mapping is the correct one to use but you need to teach the mapper operation how to instantiate the Foo objects. To do that you need to create a RKManagedObjectMappingOperationDataSource and set it as the mappingOperationDataSource.