iOS 字典和简单数据模型相互转换(通用版)
2017-08-30 15:11
148 查看
在iOS开发过程中,经常遇到将字典数据转换成model的情况,网上也有很多数据类型转换的框架,像JSONModel、MJExtension等,功能强大,有时间拜读拜读源码
在维护项目过程中,由于历史问题,并没有使用模型转换框架,每个数据模型都需要手动将字典转化为数据模型,每个模型中都产生了大量的相同的代码,就像下面这样:
觉得这样做很傻,重复造轮子,就想着优化方案,花了两三个小时,实现了基本的需求,便在这里记录一下
基本思路:
在NSObject类中新增初始化方法,将字典转换为模型对象的属性;
这样势必要得到对象的成员变量,我们可以使用运行时来得到对象的成员变量,使用KVC方式将字典中各个字段赋值给对应的属性;
针对字典的key不同于成员变量的问题,可以传递一个映射字典来解决
实现如下:
步骤一:
在NSObject中新增初始化方法
NSObject.h 文件中
.m 文件实现部分
这样,所有数据模型都可以直接调用这个方法完成字典转模型操作了,而不用在单独为每个模型编写初始化方法
简单使用:
新建Person类
使用
运行结果:
结论:
1、只针对简单数据模型(无模型嵌套),完成字典转模型操作
2、需要更多的测试,后期需要完善
3、成员变量或属性皆可
简单数据模型转字典
.h
.m
使用
Person类
结果:
补充
简单模型转json
.h
.m
使用:
结果:
在维护项目过程中,由于历史问题,并没有使用模型转换框架,每个数据模型都需要手动将字典转化为数据模型,每个模型中都产生了大量的相同的代码,就像下面这样:
觉得这样做很傻,重复造轮子,就想着优化方案,花了两三个小时,实现了基本的需求,便在这里记录一下
基本思路:
在NSObject类中新增初始化方法,将字典转换为模型对象的属性;
这样势必要得到对象的成员变量,我们可以使用运行时来得到对象的成员变量,使用KVC方式将字典中各个字段赋值给对应的属性;
针对字典的key不同于成员变量的问题,可以传递一个映射字典来解决
实现如下:
步骤一:
在NSObject中新增初始化方法
NSObject.h 文件中
#import <Foundation/Foundation.h> @interface NSObject (InitData) /** 模型初始化 @param ModelDic 模型字典 @param hintDic 映射字典,如果不需要则nil @return 模型对象 */ +(instancetype)objectWithModelDic:(NSDictionary*)modelDic hintDic:(NSDictionary*)hintDic; @end
.m 文件实现部分
#import "NSObject+InitData.h" #import <objc/runtime.h> #pragma clang diagnostic ignored "-Wobjc-designated-initializers" @implementation NSObject (InitData) +(instancetype)objectWithModelDic:(NSDictionary *)modelDic hintDic:(NSDictionary *)hintDic{ NSObject *instance = [[[self class] alloc] init]; unsigned int numIvars; // 成员变量个数 Ivar *vars = class_copyIvarList([self class], &numIvars); NSString *key=nil; NSString *key_property = nil; // 属性 NSString *type = nil; for(int i = 0; i < numIvars; i++) { Ivar thisIvar = vars[i]; key = [NSString stringWithUTF8String:ivar_getName(thisIvar)]; // 获取成员变量的名字 key = [key hasPrefix:@"_"]?[key substringFromIndex:1]:key; // 如果是属性自动产生的成员变量,去掉头部下划线 key_property = key; // 映射字典,转换key if (hintDic) { key = [hintDic objectForKey:key]?[hintDic objectForKey:key]:key; } id value = [modelDic objectForKey:key]; if (value==nil) { type = [NSString stringWithUTF8String:ivar_getTypeEncoding(thisIvar)]; //获取成员变量的数据类型 // 列举了常用的基本数据类型,如果有其他的,需要添加 if ([type isEqualToString:@"B"]||[type isEqualToString:@"d"]||[type isEqualToString:@"i"]|[type isEqualToString:@"I"]||[type isEqualToString:@"f"]||[type isEqualToString:@"q"]) { value = @(0); } } [instance setValue:value forKey:key_property]; } free(vars); return instance; } @end
这样,所有数据模型都可以直接调用这个方法完成字典转模型操作了,而不用在单独为每个模型编写初始化方法
简单使用:
新建Person类
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> typedef NS_ENUM(NSInteger , Sex) { Male, Female }; @interface Person : NSObject @property (copy ,nonatomic) NSString *name; @property (assign ,nonatomic) Sex sex; @property (assign ,nonatomic) int age; @property (assign ,nonatomic) CGFloat height; @property (assign ,nonatomic) float money; @property (copy ,nonatomic) NSDictionary *otherInfo; @property (assign ,nonatomic) BOOL isHandsome; @property (copy ,nonatomic) NSArray *familyMember; @end
使用
// 新建测试模型字典 NSDictionary *resDic = @{ @"Name":@"LOLITA0164", @"sex":@(1), @"currntAge":@(24), @"height":@"170.0", // @"money":@"0.112", // 可以没有对应字段 @"otherInfo":@{@"profession":@"iOS mobile development"}, @"isHandsome":@(YES), @"familyMember":@[@"father",@"mother",@"brother",@"older sister"], @"additional":@"我是测试条件" // 可以多余字段 }; // 映射字典 NSDictionary *hintDic = @{ @"name":@"Name", @"age":@"currntAge" }; Person *p = [Person objectWithModelDic:resDic hintDic:hintDic]; NSLog(@"\n姓名:%@\n性别:%ld\n年龄:%ld\n身高:%.1f\n存款:%.1f元\n其他信息%@\n帅不:%i\n家庭成员:%@",p.name,(long)p.sex,(long)p.age,p.height,p.money,p.otherInfo,p.isHandsome,p.familyMember);
运行结果:
结论:
1、只针对简单数据模型(无模型嵌套),完成字典转模型操作
2、需要更多的测试,后期需要完善
3、成员变量或属性皆可
简单数据模型转字典
.h
/**`这里写代码片` 模型转字典 @param hintDic 映射字典,如果不需要则nil @return 结果字典 */ -(NSDictionary*)changeToDictionaryWithHintDic:(NSDictionary*)hintDic;
.m
-(NSDictionary *)changeToDictionaryWithHintDic:(NSDictionary *)hintDic{ NSMutableDictionary *resDic = [NSMutableDictionary dictionary]; unsigned int numIvars; // 成员变量个数 Ivar *vars = class_copyIvarList([self class], &numIvars); NSString *key=nil; for(int i = 0; i < numIvars; i++) { Ivar thisIvar = vars[i]; key = [NSString stringWithUTF8String:ivar_getName(thisIvar)]; // 获取成员变量的名字 key = [key hasPrefix:@"_"]?[key substringFromIndex:1]:key; // 如果是属性自动产生的成员变量,去掉头部下划线 id value = [self valueForKey:key]; if (value!=nil) { // 映射字典,转换key if (hintDic) { key = [hintDic objectForKey:key]?[hintDic objectForKey:key]:key; } [resDic setValue:value forKey:key]; } } free(vars); return resDic; }
使用
Person类
@interface Person : NSObject { @public float height; } @property (strong ,nonatomic) NSString *name; @property ( c620 assign ,nonatomic) NSInteger age; @end
NSDictionary *dic = @{ @"name":@"LOLITA0164", @"age":@(25), @"height":@(170.0) }; Person *p = [Person objectWithModelDic:dic hintDic:nil]; // key的映射(结果字典中的key) NSDictionary *hintDic = @{ @"name":@"realName", @"age":@"currentAge" }; NSDictionary *resDic = [p changeToDictionaryWithHintDic:hintDic]; NSLog(@"%@",resDic);
结果:
补充
简单模型转json
.h
/** 模型转josn @param hintDic 映射字典 @return 结果json */ -(NSString*)changeToJsonStringWithHintDic:(NSDictionary*)hintDic;
.m
-(NSString *)changeToJsonStringWithHintDic:(NSDictionary *)hintDic{ NSDictionary *resDic = [self changeToDictionaryWithHintDic:hintDic]; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:resDic options:NSJSONWritingPrettyPrinted error:nil]; if (jsonData) { return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } return @""; }
使用:
NSDictionary *dic = @{ @"name":@"LOLITA0164", @"age":@(25), @"height":@(170.0) }; Person *p = [Person objectWithModelDic:dic hintDic:nil]; // key的映射(结果字典中的key) NSDictionary *hintDic = @{ @"name":@"realName", @"age":@"currentAge" }; NSString *resString = [p changeToJsonStringWithHintDic:hintDic]; NSLog(@"--%@",resString);
结果:
相关文章推荐
- PowerDesigner概念模型与物理模型相互转换及导出数据字典
- PowerDesigner概念模型与物理模型相互转换及导出数据字典
- 集合间相互转换,浅谈相关内存管理,使用NSData处理数据,使用NSDate - iOS
- iOS中实现plist中读取数据实现Cell的显示(字典转模型,实现按序分组)修改图片的尺寸
- iOS彩票项目--第七天,初次读取json数据、KVC转模型技巧、运行时字典转模型以及初步对显示网页的操作并且跟踪标签
- iOS NSDictionary、NSData、JSON数据类型相互转换
- [iOS]Objective-C中字符串数据类型与基础数据类型的相互转换
- iOS_OC 字典模型转换工具的比较(Mantle和MJExtension和Jsonmodel) 持续更新
- Mantle--国外程序员最常用的iOS模型&字典转换框架
- ios中常用数据类型相互转换
- 详解iOS应用UI开发中的九宫格坐标计算与字典转换模型
- MJExtension 转换速度快、使用简单方便的字典转模型框架
- iOS获取时间戳,字典转换成json数据
- 学习IOS开发UI篇--MVC设计界面及数据的模型转换
- iOS NSDictionary、NSData、JSON数据类型相互转换
- IOS将字典转换成模型对象
- iOS开发之字典数据建立模型步骤
- iOS 字典与字符串的相互转换
- MJExtension使用,数据跟模型之间的相互转换
- IPhone项目 字典,数组,服务器返回的json 一键转换数据模型的.h .m文件