美文网首页
使用Mantle解析相同名字不同类型的JSON数据

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

作者: 李俊峰 | 来源:发表于2015-04-15 19:45 被阅读1889次

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

    屏幕快照 2015-04-15 下午7.08.43.png

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

    @interface HBUser : MTLModel <MTLJSONSerializing>
    
    @property (nonatomic) NSInteger userID;
    @property (nonatomic, copy) NSString *username;
    @property (nonatomic, copy) NSString *urlname;
    @property (nonatomic, strong) HBAvatar *avatar;
    
    @end
    
    @interface HBAvatar : MTLModel <MTLJSONSerializing>
    
    @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 <MTLJSONSerializing>
    
    @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数据

          本文链接:https://www.haomeiwen.com/subject/zaysfttx.html