代码之家  ›  专栏  ›  技术社区  ›  Dirk van Oosterbosch

Restkit 0.20:POST CoreData与外键的关系

  •  4
  • Dirk van Oosterbosch  · 技术社区  · 11 年前

    我在RestKit和CoreData方面有点吃力,尤其是因为RestKit 0.20的例子和文档太少了。

    我有一个(托管)对象 Song 与多对一的关系 Album 。以下代码可以发布JSON,但不能在 压扁的 格式,服务器会例外。

    // 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和谷歌群组,但找不到适合我的案例的特定解决方案(RestKit 0.20,CoreData,仅与FK的关系)。

    谢谢,德克

    1 回复  |  直到 11 年前
        1
  •  5
  •   JD_    11 年前

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