Restkit 0.20:POST与外键的CoreData关系

时间:2013-02-26 12:41:13

标签: ios restkit foreign-key-relationship restkit-0.20

我在使用RestKit和CoreData时遇到了一些困难,特别是因为RestKit 0.20的示例和文档很少。

我有一个(托管)对象SongAlbum有多对一的关系。以下代码可以发布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应该是 flattened 外键而不是嵌套对象。但是当我试图像这样改变albumRelationshipMapping时:

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

它会引发异常。 (NSInvalidArgumentException', reason: '*** -[NSProxy doesNotRecognizeSelector:allKeys] called!'

有谁知道我在这里做错了什么?或者是否有示例代码,它可以引导我朝着正确的方向发展?

很抱歉,如果这个问题已在其他地方得到解答。我搜索了所有stackoverflow和谷歌组,但找不到我的案例的特定解决方案(RestKit 0.20,CoreData,只与FK的关系)。

谢谢,Dirk

1 个答案:

答案 0 :(得分:5)

在这种情况下,我认为您可以直接使用点符号直接获取albumID(无需使用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]];