【问题标题】:Restkit NSString includes metadataRestkit NSString 包含元数据
【发布时间】:2013-06-23 10:11:20
【问题描述】:

我有一个 JSON 文件,我从网上下载并使用 RestKit 进行解析。我的问题是,我有一个包含字符串数组的属性,我试图将其映射到他们自己的对象中。出于某种原因,在解析该字符串时,它最终会在字符串中包含元数据对象的描述。请参阅下面的代码 sn-ps 了解我目前正在使用的内容以及我遇到的错误。注意:我删除了所有核心数据集成,并尽可能地简化了我的测试,以试图找出问题所在。

对象接口

@interface BLAuthor : NSObject

@property (nonatomic, retain) NSString *name;

@end

@interface BLVolume : NSObject

@property (nonatomic, retain) NSString *id;
@property (nonatomic, retain) NSSet *authors;
@end

映射和请求操作

RKObjectMapping *volumeMapping = [RKObjectMapping mappingForClass:[BLVolume class]];
[volumeMapping addAttributeMappingsFromDictionary:@{ @"id": @"id" }];

RKObjectMapping *authorMapping = [RKObjectMapping mappingForClass:[BLAuthor class]];
[authorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil
                                                                        toKeyPath:@"name"]];


[volumeMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"volumeInfo.authors"
                                                                              toKeyPath:@"authors"
                                                                            withMapping:authorMapping]];


NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); 
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:volumeMapping
                                                                                   pathPattern:nil
                                                                                       keyPath:@"items"
                                                                                   statusCodes:statusCodes];

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com/?q=123"]];

RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
    NSLog(@"Success! %@", result);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
    NSLog(@"Failed with error: %@", [error localizedDescription]);
}];
NSOperationQueue *operationQueue = [NSOperationQueue new];
[operationQueue addOperation:operation];

JSON sn-p

{
 "items": [
  {
   "id": "abc",
   "volumeInfo": {
    "authors": [
     "123"
    ]
  }
}

结果数据 - 请注意, 实际上是 BLAuthor 上 NSString 属性的一部分:

Success! <RKMappingResult: 0x8468560, results={
    items =     (
        "<BLVolume = 0x08463F60 | id = mikPQFhIPogC | authors = {(
    <BLAuthor = 0x08466250 | name = 123 ({
    HTTP =     {
        request =         {
            URL = \"https://example.com/?q=123";
            headers =             {
            };
            method = GET;
        };
        response =         {
            URL = \"https://example.com/?q=123\";
            headers =             {
                \"Cache-Control\" = \"private, max-age=0, must-revalidate, no-transform\";
                \"Content-Type\" = \"application/json; charset=UTF-8\";
                Date = \"Sun, 23 Jun 2013 00:41:01 GMT\";
                Etag = \"\\\"I09ELXbrmOlE-RFCkDsRbIJj278/gPh8_OxpfA9YHXz_P_25F8A4orw\\\"\";
                Expires = \"Sun, 23 Jun 2013 00:41:01 GMT\";
                Server = GSE;
                \"Transfer-Encoding\" = Identity;
                \"X-Content-Type-Options\" = nosniff;
                \"X-Frame-Options\" = SAMEORIGIN;

提前感谢任何可以帮助我解决此问题的人!我束手无策 - 试图从我的测试中删除尽可能多的变量,并搜索了网络和 RestKit 的源代码以寻找原因。

【问题讨论】:

    标签: objective-c json restkit


    【解决方案1】:

    问题在于这个映射

    [authorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil
                                                                        toKeyPath:@"name"]];
    

    您基本上是在说:“将您找到的任何内容映射到 name 属性上”。

    这只能在您匹配路径而不是响应描述符中的键的情况下才有效,如建议的here。但为了这样做,您需要响应以独立返回字符串数组,这不是您的情况。

    根据同一篇文章,你可以试试

    [authorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@""
                                                                        toKeyPath:@"name"]];
    

    但我怀疑它是否可行。

    如果您可以控制 API,我建议将格式更改为更 RESTful 的格式,方法是返回完整的资源而不是数组中的纯字符串。

    【讨论】:

    • 我很欣赏这个建议,但是我已经尝试过了,但它不起作用。我在 -[RKMappingOperation valueForKeyPath:] “由于未捕获的异常 'NSUnknownKeyException' 导致应用程序终止,原因:'[<__nscfstring> valueForUndefinedKey:]:这个类不是键值键的编码兼容。'" - 它尝试获取键 @"" 的值。
    • 另外,很遗憾,我无法控制 API 对其进行任何更改!
    【解决方案2】:

    所以,我得出了一个可悲的结论 - 没有任何问题,我的代码运行良好。

    对于关系,显然 RestKit 将您的对象设置为 NSProxy 子类。子类覆盖 -description 并返回 @"%@ (%@)"、originalObject、元数据。因此,在记录对象的描述时,我得到了它,而不是 ACTUAL 对象的值。非常烦人且难以追踪。我将在 RestKit 上打开一个问题以删除这个令人困惑的描述,因为在没有 UI 的情况下构建我的应用程序时,记录 actual 对象的描述很重要。

    【讨论】:

    • 那么如果你迭代卷中的作者并打印名称属性,你会得到什么?
    • 抱歉延迟回复。我得到了实际值。但由于我将整个数据作为一个整体记录下来,它抓住了描述,让我很困惑。
    • 嗨,我也遇到了这个问题,你应该使用 [results.items.authors mutableCopy];删除元数据。见:RKMappingSourceObject
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 2011-12-24
    相关资源
    最近更新 更多