Reputation: 1546
Seems like a really easy task, but I find myself struggling.. I have this JSON response:
{"data":
{"badParams":
{"arbitraryKey":"arbitraryValue",
"arbitraryKey2":"arbitraryValue2",
"arbitraryKey3":"arbitraryValue3" ,
...
}
}
}
I'd like to parse that response to NSDictionary, containing all the key:value
pairs I got in the response:
NSDictionary *response == {"arbitraryKey":"arbitraryValue",
"arbitraryKey2":"arbitraryValue2",
"arbitraryKey3":"arbitraryValue3",...}
I tried RKDynamicMapping but couldn't make it :\
Any advise?
Upvotes: 2
Views: 3263
Reputation: 39480
If your target object is an NSDictionary, then you might be better suited to use NSJSONSerialization than RestKit. With RestKit you really don't parse JSON into dictionaries, but rather into native objective-c objects, i.e. your data models.
For more on setting up your own objects, relational mappings, and configuring the RestKit objectManager you should check out the RestKit Object Mapping Guide; they have some really solid examples on how that can be done.
UPDATE:
For a simple JSON -> NSDictionary mapping that does not require any authentication I would simply use this:
NSString *urlString = @"http://www.yourserver.com/api";
NSData *data = [NSData dataWithContentsOfURL:urlString];
NSError *error = nil;
NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
Upvotes: 3
Reputation: 372
To summarize @Xean 's solution, here is the working code snippet.
RKObjectMapping *dictionaryMapping = [RKObjectMapping mappingForClass:[RestKitDictionaryContainer class]];
[dictionaryMapping addAttributeMappingsFromArray:@[@"arbitraryKey", @"arbitraryKey2", @"arbitraryKey3"]];
then create response descriptor:
RKResponseDescriptor *responseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:dictionaryMapping
method:RKRequestMethodAny
pathPattern:@"/your/api"
keyPath:@"data.badParams"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
finally the request operation part
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];
Upvotes: 3
Reputation: 866
RestKit is not be prepared for NSDictionarys. But you could do a bit ugly workaround if it is necessary...
This class wraps a dictionary in a container class thats forwarding the KVC calls to the setObject:forKey
of the dictionary.
@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
Now you have to do all mappings as usual. After a RestKit call you only have to get the dictionary out of this class or use it as a dictionary. Well, I think this is pretty ugly and should not be used but it is your decision...
Upvotes: 5