Restkit 0.20: связь POST CoreData с внешним ключом

Я немного борюсь с RestKit и CoreData, тем более что для RestKit 0.20 так мало примеров и документации.

У меня есть (управляемый) объект Song с отношением "многие к одному" с Album. Следующий код может публиковать JSON, но не в формате flattened, за исключением сервера.

// 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];

Этот код опубликует тело JSON следующим образом:

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

Однако сервер ожидает такое тело JSON:

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

т.е. отношение album должно быть сглаженным внешним ключом, а не вложенным объектом. Но когда я пытаюсь изменить albumRelationshipMapping вот так:

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

он выдает исключение. (NSInvalidArgumentException', reason: '*** -[NSProxy doesNotRecognizeSelector:allKeys] called!')

Кто-нибудь знает, что я делаю неправильно здесь? Или есть пример кода, который может направить меня в правильном направлении?

Извините, если на этот вопрос уже отвечали где-то в другом месте. Я искал все stackoverflow и группы google, но не смог найти конкретного решения для моего случая (RestKit 0.20, CoreData, связь только с FK).

Спасибо, Дирк


person Dirk van Oosterbosch    schedule 26.02.2013    source источник


Ответы (1)


В этом случае, я думаю, вы можете просто использовать запись через точку, чтобы напрямую получить идентификатор альбома (нет необходимости использовать RKRelationshipMapping)

Попробуйте обновить код таким образом:

// 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]];
person JD_    schedule 27.02.2013
comment
Спасибо! Я думал слишком сложно. - person Dirk van Oosterbosch; 28.02.2013
comment
Я следую тому же решению, но получаю Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<Album 0x145e1680> valueForUndefinedKey:]: this class is not key value coding-compliant for the key album.' Есть идеи, почему это могло произойти? - person Zorayr; 22.10.2013
comment
@Zorayr в моем примере, альбом является свойством класса, на который вы сопоставляете. Возможно, попробуйте задать новый вопрос с некоторым кодом, если вы не найдете решения. - person JD_; 22.10.2013