ios - 根据请求的参数映射资源

标签 ios objective-c restkit json-rpc

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

对于事件:

{
    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 方法之后调用的,因此目前我从后端收到的所有内容都被视为 Podcast

有谁知道区分这两个响应并将每个请求的响应映射到正确实体的方法吗?

更新:响应

这是我对我的资源得到的回应:

事件

{
  "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 中实现它,这不一定是微不足道的。

关于ios - 根据请求的参数映射资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27805421/

相关文章:

ios - RestKit:同步发布多个对象

ios - Restkit - 删除具有相同 URL 路径的孤立对象

ios - 如何在 Swift 的小数位拆分字符串?

ios - iOS 中的 -(CGRect *)frame 方法是什么?

iphone - UITableView Sectionheaders 每个都有一个按钮,但只有第一个按钮发送操作

objective-c - 如何在基于 WebKit 的应用程序中启用本地存储?

google-analytics - Restkit和Google Analytics(分析)

ios - Navigation Bar 向上移动,同时 Navigation Controller 弹出动画

ios 应用程序 - 设置数据库 user_version

ios - 当应用程序终止且电话被锁定时,VOIP 推送代表不会调用