根据请求的参数映射资源

时间:2015-01-06 19:05:37

标签: ios objective-c restkit json-rpc

我的应用程序正在使用协议JSON-RPC与后端进行通信。我基本上想要做的是获取对象并将它们直接存储在Core Data中。我有多种类型的实体。我们举个例如活动播客。我通过在两个实体的POST请求中在同一端点点击API来获取它们。唯一改变的是params:

对于活动:

{
    id = 0;
    jsonrpc = "2.0";
    method = "Events.Event.list";
    params =     {
        location =         {
            type = token;
            value = haHssQWR0V8d;
        };
        sessionId = v1oCLGlfxIvqYxhaHssQWR0V8dkFeS1JUqlF;
        week = "2014_42";
    };
}

播客:

{
    id = 1;
    jsonrpc = "2.0";
    method = "Podcasts.Podcast.list";
    params =     {
        sessionId = v1oCLGlfxIvqYxhaHssQWR0V8dkFeS1JUqlF;
    };
}

我目前正在为每个实体映射创建响应描述符。

+ (void)configureAllObjectsMapping
{
    [self mapEvent];
    [self mapPodcast];
}

+ (RKEntityMapping *)mapEvent
{
    if (_eventMapping) {
        return _eventMapping;
    }

    _eventMapping = [self mappingForClass:[Event class]];
    _eventMapping.identificationAttributes = @[CoreDataPrimaryKey];
    [_eventMapping addAttributeMappingsFromDictionary:@{
                                                        @"token":@"token",
                                                        @"name":@"name",
                                                        @"urlWeb":@"urlWeb",
                                                        @"urlImage":@"urlImage",
                                                        @"startsAt":@"startsAt",
                                                        @"endsAt":@"endsAt",
                                                        @"costs":@"costs",
                                                        @"description":@"desc",
                                                        @"genres":@"genres",
                                                        @"artists.isSecret":@"hasSecretArtist",
                                                        @"hasGuestlist":@"hasGuestlist",
                                                        @"countGoings":@"countGoings"
                                                        }];

    [_eventMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"venue"
                                                                                  toKeyPath:@"venue"
                                                                                withMapping:[self mapVenue]]];

    [_eventMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"artists.data"
                                                                                  toKeyPath:@"artists"
                                                                                withMapping:[self mapArtist]]];

    RKResponseDescriptor *list = [RKResponseDescriptor responseDescriptorWithMapping:_eventMapping
                                                                              method:RKRequestMethodPOST
                                                                         pathPattern:nil
                                                                             keyPath:@"result.data"
                                                                         statusCodes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(RKStatusCodeClassSuccessful, 104)]];

    [[APIManager sharedInstance].manager addResponseDescriptor:list];

    return _eventMapping;
}

+ (RKEntityMapping *)mapPodcast
{
    if (_podcastMapping) {
        return _podcastMapping;
    }

    _podcastMapping = [self mappingForClass:[Podcast class]];
    _podcastMapping.identificationAttributes = @[CoreDataPrimaryKey];
    [_podcastMapping addAttributeMappingsFromDictionary:@{
                                                        @"token":@"token",
                                                        @"name":@"name",
                                                        @"urlWeb":@"urlWeb",
                                                        @"urlImage":@"urlImage",
                                                        @"description":@"desc",
                                                        @"duration":@"duration",
                                                        @"playCount":@"playCount"
                                                        }];

    RKResponseDescriptor *list = [RKResponseDescriptor responseDescriptorWithMapping:_podcastMapping
                                                                              method:RKRequestMethodPOST
                                                                         pathPattern:nil
                                                                             keyPath:@"result.data"
                                                                         statusCodes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(RKStatusCodeClassSuccessful, 104)]];

    [[APIManager sharedInstance].manager addResponseDescriptor:list];

    return _podcastMapping;
}

问题是Podcast和Event实体的响应描述符是相同的,因为pathPattern是nil。

因此,我从后端收到的所有内容目前都被认为是播客,因为在mapPodcast方法之后调用了mapEvent方法。

是否有人知道如何区分这两个回复并将每个请求的回复映射到正确的实体?

更新响应

这是我对资源的回应:

事件

{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "count": 1,
    "data": [
      {
        "token": "YAXDMJG17GRO",
        "event_name": "Klubnacht | Fachwerk Nacht",
        ...
      }
    ]
  }
}

播客

{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "count": 1,
    "data": [
      {
        "token": "G17GROYAXDMJ",
        "podcast_name": "Podcast #19",
        ...
      }
    ]
  }
}

所以没有任何事件可以区分它们,除了一些参数名称。

1 个答案:

答案 0 :(得分:1)

您唯一的简单解决方案是使用动态映射来检查响应中的数据并选择正确的映射(因此您将有一个指向此动态映射的响应描述符)。

你可以通过@metadata在映射过程中使用参数,但在这种情况下,这不会帮助你,它真的可以区分不同类型的同一个实体。

此时,您无法使用参数进行动态映射选择或响应描述符选择。你可以考虑在RestKit中实现它,它不一定是微不足道的。