iosobjective-cjsonparsinggithub-mantle

Mantle 2.0 cannot parse JSON for the notation in array nested


The following codes parsing JSON don't work any more for me after I update Mantle to 2.0. They can work fine on an older Mantle version( I don't remember the correct version number. What I know is I downloaded it in Nov of 2013.)

Here is the JSON content:

{
    date = "2015-05-21";
    error = 0;
    results = (
            {
            currentCity = "beijing";
            index = (
                {
                    des = "desc1";
                    tipt = "tipt1";
                    title = "title1";
                    zs = "zs1";
                },
                {
                    des = "desc2";
                    tipt = "tipt2";
                    title = "title2";
                    zs = "zs2";
                },
                {
                    des = "desc3";
                    tipt = "tipt3";
                    title = "title3";
                    zs = "zs3";
                }
            );         
        }
    );
    status = success;
}

The Model I defined:

// .h
#import "MTLModel.h"
#import "Mantle.h"

@interface BaiduWeatherResults : MTLModel<MTLJSONSerializing>

@property (nonatomic, strong) NSNumber *error;
@property (nonatomic, strong) NSString *status;
@property (nonatomic, strong) NSString *date;
@property (nonatomic, strong) NSString *currentCity;

@end


// .m
#import "BaiduWeatherResults.h"

@implementation BaiduWeatherResults

+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
    return @{
             @"error"   : @"error",
             @"status"  : @"status",
             @"date"    : @"date",
             @"currentCity" : @"results.currentCity",
             };
}

+ (NSValueTransformer *) currentCityJSONTransformer
{
    return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSArray *values) {
        return [values firstObject];
    } reverseBlock:^(NSString *str) {
        return @[str];
    }];
}

Parse JSON to Model

id results =[MTLJSONAdapter modelOfClass:[BaiduWeatherResults class]
                        fromJSONDictionary:responseObject
                                     error:nil];

NSLog(@"results:%@", results);

My Question:

The codes can work on an older Mantle. On the Mantle 2.0, the parse failed once I added @"currentCity" : @"results.currentCity" into the dictionary returned by JSONKeyPathsByPropertyKey . Anyone know what I missed for the parsing?

BTW, the currentCityJSONTransformer did call when the parse began. But the transformer is never used, because the line "return [values firstObject];" is never executed.

Thanks in advance.


Solution

  • Try this -

    + (NSDictionary *)JSONKeyPathsByPropertyKey
    {
        return @{
                 @"error"   : @"error",
                 @"status"  : @"status",
                 @"date"    : @"date",
                 @"currentCity" : @"results",
                 };
    }
    
    + (NSValueTransformer *) currentCityJSONTransformer
    {
        return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSArray *values) {
            NSDictionary *cityInfo = [values firstObject];
            return cityInfo[@"currentCity"];
        } reverseBlock:^(NSString *str) {
            return @[@{@"currentCity" : str}];
        }];
    }
    

    Since results is an array of dictionaries, you can't access currentCity via dot syntax in JSONKeyPathsByPropertyKey. Instead the currentCityJSONTransformer finds the first dictionary in the results array and returns its value for currentCity. You might want to add type-checking and define the @"currentCity" key in a single place.