I'm using RestKit on iOS to retrieve some data from kraken.com
I have the following JSON data:
{
"error":[],
"result":{
"XXBTZUSD":{
"a":["475.00000","1"],
"b":["465.00639","2"],
"c":["475.00000","0.01000389"],
"v":["1.01078477","1.01078477"],
"p":["475.00008","475.00008"],
"t":[6,6],
"l":["475.00000","475.00000"],
"h":["475.00013","475.00013"],
"o":"475.00001"
}
}
}
My keyPath is @"result.XXBTZUSD" and I'm interested in the first member of the array in each property, i.e. 'a', 'b', 'c', and so on with the exception of 'o' as its value isn't an array. To be clear, an example value I'm interested in would be "475.00000" for 'a'. I am trying to map these values to NSNumber properties in my own data model.
Aside: I would be doing this dynamically, as I am also getting similar data from other sources but with different structured data.
Also, I don't believe I can use RKObjectMappingMatchers because I don't have an "expected value" for this data.
EDIT:
I've continued working on my RKDynamicMapping and RKBlockValueTransformer logic:
RKDynamicMapping *dynamicMapping = [RKDynamicMapping new];
[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation)
{
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:class];
if ([url.absoluteString isEqualToString:@"https://api.kraken.com"])
{
RKBlockValueTransformer *arrayToNumberValueTransformer = [RKBlockValueTransformer valueTransformerWithValidationBlock:^BOOL(__unsafe_unretained Class inputValueClass, __unsafe_unretained Class outputValueClass) {
BOOL isTransformableValue = NO;
if ([inputValueClass isSubclassOfClass:[NSArray class]] && [outputValueClass isSubclassOfClass:[NSNumber class]])
{
isTransformableValue = YES;
}
return isTransformableValue;
} transformationBlock:^BOOL(id inputValue, __autoreleasing id *outputValue, __unsafe_unretained Class outputClass, NSError *__autoreleasing *error) {
RKValueTransformerTestInputValueIsKindOfClass(inputValue, [NSArray class], error);
RKValueTransformerTestOutputValueClassIsSubclassOfClass(outputClass, [NSNumber class], error);
*outputValue = [[NSNumber alloc] initWithDouble:[[inputValue objectAtIndex:0] doubleValue]];
return YES;
}];
arrayToNumberValueTransformer.name = @"ArrayToNumberValueTransformer";
[[RKValueTransformer defaultValueTransformer] insertValueTransformer:arrayToNumberValueTransformer atIndex:0];
}
if (sourceKeyPath && [sourceKeyPath length] > 0)
{
// Special case (ignore):
if ([url.absoluteString isEqualToString:@"http://blockchain.info"])
{
[mapping addAttributeMappingsFromDictionary:@{sourceKeyPath:@"currencyCode"}];
}
//
// The following is useful if you're expecting a set but the service returns a single value
//[mapping setForceCollectionMapping:YES]; // RestKit cannot infer this information on its own
//
}
// Where a 'key' is the JSON representation and its value is the internal object representation
NSDictionary *attributeMappings = [query objectForKey:@"attributeMappings"];
[mapping addAttributeMappingsFromDictionary:attributeMappings];
return mapping;
}];
EDIT:
I've got data being mapped now however I'm not sure that I am inserting my RKBlockValueTransformer into the default value transformers list properly? If I insert at 0 will I break something with the functionality of other default value transformers?
RKValueTransformer?objectAtIndex:0ifarray count > 1? Or am I missing something?addValueTransformer:instead but from other examples I've seen, they've been inserting them. Also looping isn't an option as the internal structure of RKValueTransformer is controlled at a lower level.