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

今天在使用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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,686评论 25 708
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,196评论 6 13
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,956评论 0 15
  • 失眠原是忆青春,考试从来未满分。 多少同窗断消息,犹能联系二三人。
    林月寒阅读 228评论 1 2
  • 赞美的力量很伟大 一天无意中看到群里老师们发了一篇文章,有几句话触动了我。对孩子教育过程中,赞美讲究...
    肖睿妈妈阅读 112评论 0 0