根据请求的参数映射资源

Map resources depending on the request's parameters

我的应用程序使用 JSON-RPC 协议与后端通信。我基本上想做的是获取对象并将它们直接存储在核心数据中。我有多种类型的实体。让我们以 EventsPodcasts 为例。我通过在同一个端点上点击 API 来获取它们,同时对两个实体发出 POST 请求。唯一改变的是参数:

对于事件:

{
    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。

因此,我从后端收到的所有内容目前都被认为是 Podcast,因为 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",
        ...
      }
    ]
  }
}

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

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

您可以通过@metadata 在映射期间使用参数,但这在这种情况下对您没有帮助,它实际上是为了区分同一实体的不同类型。

目前您不能将参数用于动态映射选择或响应描述符选择。您可以考虑在 RestKit 中实现它,这不一定是微不足道的。