iOS网络请求到的json数据需要手动setter/getter序列化到具体的model对象,但这种写法就觉得不太优美,有时候model对象重用的时候还要重复的写setter。询问小伙伴,推荐一个名为jastor的对象序列化库,这个库可以序列化普通对象,但是对NSDate和CoreData的支持不完美或者说根本不支持。另外Restkit一大亮点也是支持对象自动映射,可同样不支持CoreData对象,况且Restkit框架还不够成熟。
参考Restkit对象映射的设计风格以及jastor对runtime的处理方式,我自己封装了一个映射库:magicalMapping. 支持coredata和NSDate的序列化。
######用法:
一.导入文件,添加CoreData.framework框架. ARC的项目需要做编译处理(-fno-objc-arc)
二.新建一个班级对象ClassObj(示例)
1 | #import <Foundation/Foundation.h> |
.m文件中propertyNameMapping方法返回一个映射字典,其中key代表json中对象的字段名称,而value代表ClassObj对象属性名称,这里的值必须和对象的属性值一样。其实对象映射完全可以通过runtime api 动态获取对象的属性然后进行赋值映射,可这样带来的坏处就是如果解析出来的json有一个字段为description, 而description是NSObject的保留字,赋值当然也就会失败。所以手动创新对象映射字典的好处就是可以保证model对象的属性名和json对象的字段名称可以不一致。
propertyTypeFormat方法是为了处理NSDate和复杂属性而设置的。例如ClassObj有个属性studentMembers,它是数组类型。当数组为空时runtime也没法知道里面到底存取什么类型的对象,所以需要人工指定。json返回的日期为string类型,映射为NSDate是需要指定NSDateFormatter的格式,所以使用了”createDate”:@”yyyy-MM-dd HH:mm”. (关于这一点我也很惆怅,通过正则表达式可以自动判断出NSDateFormatter,可公司的服务器编程老喜欢返回不同格式的date字符串,而且毫无规律可言。所以这个字段就手工设置NSDateFormatter好了)
创建coredata对象时,推荐使用Mogenerator(教程见文章底部链接),这样就不必每次重建model都要重新写propertyNameMapping和propertyTypeFormat方法了。
三。设置完对象后,下面进行映射 ,json解析用的是jsonkit
1 | NSURL * url =[NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:@"data" ofType:@"json"]]; |
另外 magicalMapping基于KVC,所以model的必须使用规范化的命名,如bool,int,doube等类型必须使用NSNumber替代(这在coredata中都是自动实现的),但是普通model中除了bool类型,其它定义为int,double类型的好像也映射成功了。
大家有兴趣的可以下载看看,也希望提出宝贵意见。新浪微博 @Nidom
完整demo
https://github.com/nidom/magicalMapping
Mogenerator的使用