使用Mantle解析相同名字不同类型的JSON数据

今天在使用Mantle解析返回的JSON数据时,遇到一个问题。问题是这样子的。当我向服务器请求数据时,返回如下JSON数据:

使用Mantle解析相同名字不同类型的JSON数据_第1张图片
屏幕快照 2015-04-15 下午7.08.43.png

基于以上数据我建立了HBUser类和HBAvatar类。

@interface HBUser : MTLModel 

@property (nonatomic) NSInteger userID;
@property (nonatomic, copy) NSString *username;
@property (nonatomic, copy) NSString *urlname;
@property (nonatomic, strong) HBAvatar *avatar;

@end

@interface HBAvatar : MTLModel 

@property (nonatomic) NSInteger ID;
@property (nonatomic, copy) NSString *farm;
@property (nonatomic, copy) NSString *bucket;
@property (nonatomic, copy) NSString *key;
@property (nonatomic, copy) NSString *type;
@property (nonatomic) NSInteger width;
@property (nonatomic) NSInteger height;
@property (nonatomic) NSInteger frames;

@end

为了解析嵌套的HBAvatar类,我们只需在HBUser类里添加如下代码即可。

+ (NSValueTransformer *)avatarJSONTransformer
{
    return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:[HBAvatar class]];
}

如果不出意外的话,这些是没问题的。那么问题来了,服务端是这样返回数据的,当有头像时,返回HBAvatar类;当没有头像时,它返回了个字符串类型。这样当遇到没有头像的情况,解析就会崩溃,说返回的avatar字段不是字典。
遇到这样返回数据我被卡了一下午,没有丝毫办法。因为返回的数据名字相同但是类型不同,让我一筹莫展。后来问了下同事,同事想了个办法成功解决掉这个问题。在这里记录下这个解决方法。
第一步,因为返回的类型不确定,把avatar的类型改为id
@property (nonatomic, strong) id avatar;
第二步,去掉如下代码。依然会解析avatar属性,只是按照id类型来解析。

+ (NSValueTransformer *)avatarJSONTransformer
{
    return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:[HBAvatar class]];
}

第三步,添加bhAvatar属性,以后用它来代替avatar属性在代码其他地方使用。
@property (nonatomic, strong) HBAvatar *hbAvatar;
第四步,在HBUser里面添加如下方法。如果avatar是字典类型,就把它赋值给hbAvatar。这样当有头像时,hbAvatar里就有相应的数据;当没有头像时,hbAvatar即为空。

- (HBAvatar *)hbAvatar
{
    if ([_avatar isKindOfClass:[NSDictionary class]]) {
      //_hbAvatar = (HBAvatar *)_avatar; 这样写不对,要写成下面这样
        _hbAvatar = [MTLJSONAdapter modelOfClass:[HBAvatar class] fromJSONDictionary:_avatar error:nil]; 
    }
    
    return _hbAvatar;
}

最后的代码是这个样子的。

@interface HBUser : MTLModel 

@property (nonatomic) NSInteger userID;
@property (nonatomic, copy) NSString *username;
@property (nonatomic, copy) NSString *urlname;
@property (nonatomic, strong) id avatar;
@property (nonatomic, strong) HBAvatar *hbAvatar;

@end

@implementation HBUser

+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
    return @{
             @"userID": @"user_id",
             };
}

- (HBAvatar *)hbAvatar
{
    if ([_avatar isKindOfClass:[NSDictionary class]]) {
        //_hbAvatar = (HBAvatar *)_avatar; 这样写不对,要写成下面这样
        _hbAvatar = [MTLJSONAdapter modelOfClass:[HBAvatar class] fromJSONDictionary:_avatar error:nil];
    }
    
    return _hbAvatar;
}

@end

你可能感兴趣的:(使用Mantle解析相同名字不同类型的JSON数据)