1

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?

7
  • 1
    Have you looked at nil key path mappings and a custom RKValueTransformer? Commented Sep 18, 2014 at 8:20
  • I've made an attempt at what you've suggested. Any further thoughts? Commented Sep 23, 2014 at 20:35
  • Regarding nil key path mappings... Are you suggesting that I traverse a dictionary instead since what's being returned is a set of attribute-value pairs? I feel like that may produce more difficult code to work with. Commented Sep 23, 2014 at 20:54
  • Can't you just forloop on objectAtIndex:0 if array count > 1 ? Or am I missing something? Commented Sep 23, 2014 at 21:03
  • I could choose to 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. Commented Sep 23, 2014 at 21:12

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.