使用KVC进行字典转模型

在项目中我们一般的都会碰到Json字段请求回来进行模型封装的情况,一般我们是建立一个Model然后Model里面有Json请求回来的模型字典里的各种字段,类似 name,age…….之类的。封装的时候拿到对应的模型字典,然后分别进行各个字段的赋值,这个动作按照MVC的机制,一般都是放在模型里面进行处理。类似于

-(void)toModelFromDictionary:(NSDictionary*)jsonDic{
self.name = jsonDic[@"name"];
self.age  = jsonDic[@"age"];
}

这样的话有几个弊端:
1、后台请求回来的字典数据有可能是各种类型的,比如NSNumber,Nsstring,等,如果后台的某个字段为空,那么就会导致程序崩溃。
2、字段比较多的话,手写字典转模型就很累人了。。

解决办法有两个:
1. 使用一个第三方控件,李明杰老师的MJExtension,这个控件可以做到字典转模型,模型里面还可以套结模型,也可以套接模型数组,功能比较完善和强大。
功能点:
JSON –> Model、Core Data Model
JSONString –> Model、Core Data Model
Model、Core Data Model –> JSON
JSON Array –> Model Array、Core Data Model Array
JSONString –> Model Array、Core Data Model Array
Model Array、Core Data Model Array –> JSON Array
Coding all properties of model in one line code.

https://github.com/CoderMJLee/MJExtension

  1. 如果你不想用第三方控件,感觉自由度太低,比较受限制,那么可以尝试这种方法,使用 KVC 机制的 如下方法
- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;

这个函数能够做到的事情就是把模型里对应的属性按照keyedValues里的字典键值对进行复制,完成模型的初步转化,这里注意,如果你不做任何处理,那么模型里的属性类型必须和字典里的值对应,比如字典里的时NSnumber 那么属性类型也必须是NSnumber.

有没有办法让所有的类型统一一下,处理起来没这么麻烦要做到类型的一一对应?可以在模型里实现如下方法,系统自动调用

// 将所有的数据转换为字符串
-(void)setValue:(id)value forKey:(NSString *)key{

    if([value isKindOfClass:[NSNull class]]){
        value=nil;
    }else if([value isKindOfClass:[NSArray class]]){
    }else{
        value = [NSString stringWithFormat:@"%@",value];
    }
    [super setValue:value forKey:key];
}

// 对特殊字符 id 进行处理
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
    NSLog(@"Undefined Key: %@", key);
}

可以封装一个BaseModel 实现上面两个方法,创建如下转模型方法

// 字典转模型
-(id)initWithDic:(NSDictionary *)modelDic{

    self = [super init];
    if(self){
        [self setValuesForKeysWithDictionary:modelDic];
    }
    return self;

}

使用的时候大概是这样:

EmployeModel *aEmploye = [[EmployeModel alloc]initWithDic:employeeDic];

如果我们还想要进行模型里的模型嵌套,或者模型里的模型数组或者其他处理怎么办?
在EmployeModel里面复写BaseModel里面的 setValueForKey比如我的EmployeModel里面还有个times 的字典数组,数组里面又是模型,单独处理。除此之外,我们还可以进行其他的一些数据微调处理。

- (void)setValue:(id)value forKey:(NSString *)key{

//    去掉从通讯录导出来时出现的 -
    if ([key isEqualToString:@"mobile"]) {
        NSArray *arr = [(NSString *)value componentsSeparatedByString:@"-"];
        value = [arr componentsJoinedByString:@""];
    }else if([key isEqualToString:@"times"]){

        NSMutableArray *retArr = [NSMutableArray array];

        for (int i=0; i<((NSArray *)value).count; i++) {

            NSDictionary * aDayTimeDic = ((NSArray *)value)[i];
            TimeModel *aDayTime = [[TimeModel alloc]initWithDic:aDayTimeDic];
            [retArr addObject:aDayTime];

        }
        value = retArr;
    }
    [super setValue:value forKey:key];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值