1

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

对象接口

@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 片段

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

结果数据 - 请注意,<BLAuthor = 0x08466250 |之后的所有内容 name = 实际上是 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;

Thanks in advance to anyone who can help me resolve this! I'm at wits end - tried to remove as many variables from my testing as I can, and have searched both the web and RestKit's source looking for the cause.

4

2 回答 2

1

The problem is with this mapping

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

You're basically saying: "map whatever you find onto the name property".

This can only work in case you're matching the path as opposed to the key in the response descriptor, as suggested here. But in order to do so, you would need the response to return the string array standalone, which is not your case.

As per the same post, you can try with

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

but I am skeptical it could work.

If you have control over the APIs, I'd suggest to change the format to a more RESTful one, by returning full-fledged resources instead of plain strings inside the array.

于 2013-06-23T00:59:25.917 回答
1

So, i've come to a sad conclusion - nothing is broken, my code works perfectly.

With relationships, apparently RestKit sets your objects to an NSProxy subclass. The subclass overrides -description and returns @"%@ (%@)", originalObject, metadata. So when logging the description of the object, I get that, instead of the ACTUAL objects' value. Very irritating and difficult to track down. I'm going to be opening an issue on RestKit to remove this confusing description, as when building my app without a UI yet, logging the description of the actual object is important.

于 2013-06-23T02:11:20.797 回答