Targeting JSON internal array data and using RKValueTransformer in RestKit

元气小坏坏 提交于 2019-12-11 11:41:14

问题


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?

来源:https://stackoverflow.com/questions/25903450/targeting-json-internal-array-data-and-using-rkvaluetransformer-in-restkit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!