2013-08-02 123 views
2

似乎是一个很容易的事,但我发现自己挣扎.. 我有这样的JSON响应:Restkit简单的NSDictionary映射

{"data": 
    {"badParams": 
     {"arbitraryKey":"arbitraryValue", 
     "arbitraryKey2":"arbitraryValue2", 
     "arbitraryKey3":"arbitraryValue3" , 
     ... 
     } 
    } 
} 

我想解析到的NSDictionary该响应,包含所有key:value对我的回应了:

NSDictionary *response == {"arbitraryKey":"arbitraryValue", 
      "arbitraryKey2":"arbitraryValue2", 
      "arbitraryKey3":"arbitraryValue3",...} 

我试图RKDynamicMapping但不能使它:\

任何建议?

+0

使用NSJSONSerialization,分析该字符串,做'响应= jsonResult [@ “数据”] [@ “badParams”];'你已经明白了。 –

回答

3

如果您的目标对象是NSDictionary,那么您可能会比RestKit更适合使用NSJSONSerialization。使用RestKit,您实际上不会将JSON解析为字典,而是将其解析为本机Objective-c对象,即您的数据模型。

有关设置您自己的对象,关系映射和配置RestKit objectManager的更多信息,请查看RestKit Object Mapping Guide;他们有一些非常可靠的例子来说明如何做到这一点。

UPDATE:

对于一个简单的JSON - >不需要任何身份验证的NSDictionary映射我只想用这个:

NSString *urlString = @"http://www.yourserver.com/api"; 
NSData *data = [NSData dataWithContentsOfURL:urlString]; 
NSError *error = nil; 
NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
+0

所以你说解析到原始NSDictionary是不可能的?这个请求只是完整程序的一部分,所以在这里需要Restkit(而不是NSJSONSerialization)。 – Rizon

+0

@Rizon - “raw NSDictionary”是什么意思?上面的代码返回一个NSDictionary,并且执行'parsedData [data“] [@”badParams“]'会让你进入你想要的内部字典。 –

+1

非常简单的解决方案。确保把它放在后台线程上去生产中使用它 –

5

RestKit不是为NSDictionarys准备。但是,如果有必要,你可以做一个丑陋的解决方法...

此类包装容器类中的字典,将KVC调用转发到字典的setObject:forKey

@interface RestKitDictionaryContainer : NSObject 
@property (nonatomic, strong) NSMutableDictionary * dictionary; 
@end 

@implementation RestKitDictionaryContainer 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     _dictionary = [NSMutableDictionary dictionary]; 
    } 
    return self; 
} 

-(void)setValue:(id)value forUndefinedKey:(NSString *)key 
{ 
    [_dictionary setObject:value forKey:key]; 
} 

-(id)valueForUndefinedKey:(NSString *)key { 
    return [_dictionary objectForKey:key]; 
} 
@end 

现在您必须照常进行所有映射。 RestKit调用后,您只需将字典从此类中取出或将其用作字典即可。 嗯,我认为这是非常丑陋的,不应该使用,但它是你的决定...

+0

真的很棒的解决方法,像魅力一样工作 – Songlin

+0

真的很棒! – Chengjiong

3

总结@Xean的解决方案,这里是工作代码片段。

RKObjectMapping *dictionaryMapping = [RKObjectMapping mappingForClass:[RestKitDictionaryContainer class]]; 
[dictionaryMapping addAttributeMappingsFromArray:@[@"arbitraryKey", @"arbitraryKey2", @"arbitraryKey3"]]; 

然后创建响应描述符:

RKResponseDescriptor *responseDescriptor = 
[RKResponseDescriptor responseDescriptorWithMapping:dictionaryMapping 
              method:RKRequestMethodAny 
             pathPattern:@"/your/api" 
              keyPath:@"data.badParams" 
             statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 

最后请求操作部

RKObjectRequestOperation *objectRequestOperation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]]; 
[objectRequestOperation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
    NSString *value = [((RestKitDictionaryContainer *)[[mappingResult dictionary] objectForKey:@"content"]).dictionary objectForKey:@"arbitraryKey"]; 
      //.... 
} failure:^(RKObjectRequestOperation *operation, NSError *error) { 
    RKLogError(@"Operation failed with error: %@", error); 
}]; 
[objectRequestOperation start];