Question

I'm struggling a bit with RestKit and CoreData, especially since there are so little examples and documentation out there for RestKit 0.20.

I have an (managed) object Song with a many-to-one relationship with Album. The following code can post JSON, but not in the flattened format, which the server excepts.

// Defined elsewhere
Album *theAlbum;
RKObjectManager *objMan = [self objectManager];

// Response Mapping
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[Song class]];
[responseMapping addAttributeMappingsFromDictionary:@{ @"song": @"songID" }];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping
                                                                                   pathPattern:@"/api/song"
                                                                                       keyPath:nil
                                                                                   statusCodes:statusCodes];

// Request Mapping
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
RKEntityMapping *albumRelationshipMapping = [RKEntityMapping mappingForEntityForName:@"Album" inManagedObjectStore:[objMan managedObjectStore]];
[albumRelationshipMapping addAttributeMappingsFromDictionary:@{@"id": @"albumID", }];
[requestMapping addAttributeMappingsFromDictionary:@{ @"title": @"title", @"length": @"length" }];
[requestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"album"
                                                                               toKeyPath:@"album"
                                                                             withMapping:albumRelationshipMapping]];
requestMapping = [requestMapping inverseMapping];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[Song class] rootKeyPath:nil];

[objMan addRequestDescriptor:requestDescriptor];
[objMan addResponseDescriptor:responseDescriptor];

// Create a new temporary song object
Song *song = [NSEntityDescription insertNewObjectForEntityForName:@"Song"
                                                inManagedObjectContext:[[objMan managedObjectStore] mainQueueManagedObjectContext]];
song.title = @"Some Title";
song.length = 123;
song.album = theAlbum;

// Post operation
objMan.requestSerializationMIMEType = RKMIMETypeJSON;
RKManagedObjectRequestOperation *operation = [objMan appropriateObjectRequestOperationWithObject:song
                                                                                          method:RKRequestMethodPOST
                                                                                            path:@"/api/song"
                                                                                      parameters:nil];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    // Success
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
    // Failure
}];
[objMan enqueueObjectRequestOperation:operation];

This code will post a JSON body like this:

{"title":"Some Title","length":"123","album":{"id":"6e32ae476815f365"}}

However, the server expects a JSON body like this:

{"title":"Some Title","length":"123","album":"6e32ae476815f365"}

I.e. the relationship album should be a flattened foreign key instead of a nested object. But when I try to alter the albumRelationshipMapping like this:

[albumRelationshipMapping setIdentificationAttributes:@[ @"albumID" ]];
[albumRelationshipMapping addAttributeMappingToKeyOfRepresentationFromAttribute:@"albumID"];

it throws an exception. (NSInvalidArgumentException', reason: '*** -[NSProxy doesNotRecognizeSelector:allKeys] called!')

Anybody knows what I'm doing wrong here? Or is there example code out there, which can steer me in the right direction?

Sorry if this question was already answered somewhere else. I searched all of stackoverflow and the google groups, but couldn't find a specific solution for my case (RestKit 0.20, CoreData, relationship with just a FK).

Thanks, Dirk

Was it helpful?

Solution

In this case, I think you can simply use the dot notation to get albumID directly (no need to use RKRelationshipMapping)

Try updating your code this way :

// Request Mapping
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
RKEntityMapping *albumRelationshipMapping = [RKEntityMapping mappingForEntityForName:@"Album" inManagedObjectStore:[objMan managedObjectStore]];
//[albumRelationshipMapping addAttributeMappingsFromDictionary:@{@"id": @"albumID", }];
//[requestMapping addAttributeMappingsFromDictionary:@{ @"title": @"title", @"length": @"length" }];
[requestMapping addAttributeMappingsFromDictionary:@{ @"title": @"title", @"length": @"length", @"album" : @"album.albumID" }];
//[requestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"album"
//                                                                               toKeyPath:@"album"
//                                                                             withMapping:albumRelationshipMapping]];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top