一种模型对象与JSON对象互转的方法和装置
技术领域
本发明涉及计算机领域,尤其涉及一种模型对象与JSON对象互转的方法和装置。
背景技术
现有的iOS***中,模型对象与JSON对象之间的转换时通过API(ApplicationProgramming Interface,应用程序编程接口)动态获取模型对象的所有属性,并结合一些算法实现的。具体有以下两种实现方式:方式一:获取所有属性之后,以属性名为Key(键),调用-[NSObjectvalueForKey:]接口或者调用Get方法获取属性值,并以Key-Value(键值对)的形式存储在字典(NSDictionary)内,然后调用+[NSJSONSerializationdataWithJSONObject:options:error:]接口转换为JSON数据。方式二:通过JSONModel模型框架实现模型对象与JSON对象之间的转换。其中,iOS***为苹果公司开发的移动操作***;JSON是一种轻量级的数据交换格式。
在实现本发明过程中,发明人发现现有技术中至少存在如下问题:
方式一只支持NSString属性类型的转换,不支持模型对象嵌套、不支持数组(NSArray)内的模型对象。方式二能支持上述转换,但是实现算法和接口复杂,代码量大,不易使用。
发明内容
有鉴于此,本发明实施例提供一种模型对象与JSON对象互转的方法和装置,包括一种将模型对象转换为JSON对象的方法和装置,以及一种将JSON对象转换为模型对象的方法和装置。该实施例在获取模型对象的属性值后,判断属性值的类型,如果所述属性值为预定义的工具类的实例,则使用递归算法生成JSON对象,实现了嵌套有其他模型对象的模型对象到JSON对象的转换。
为实现上述目的,根据本发明实施例的一个方面,提供了一种将模型对象转换为JSON对象的方法的方法。
本发明实施例的一种将模型对象转换为JSON对象的方法的方法,包括:获取预定义的模型对象的属性,以得到所述属性对应的属性名;从实例化后的模型对象中获取所述属性名对应的属性值;判断所述属性值是否为预定义的工具类的实例,若所述属性值为所述工具类的实例,则通过递归算法生成JSON对象,其中,所述工具类为所述模型对象的父类。
可选地,所述从实例化后的模型对象中获取所述属性名对应的属性值的步骤之后,还包括:判断所述属性值是否为数组,若所述属性值为数组且所述数组的数组元素被标记为可JSON化的模型对象,则判断所述数组元素是否为所述模型对象的实例;当所述数组的数组元素为所述模型对象的实例时,将所述数组元素转换为所述JSON对象。
可选地,所述方法还包括:将所述数组元素标记为可JSON化的模型对象;将所述模型对象的类名以及所述属性名作为键,将所述数组元素作为值进行存储,以判断所述数组的数组元素是否被标记为可JSON化的模型对象。
可选地,获取所述属性对应的属性名,包括:获取所述属性对应的属性类型,判断所述属性类型是否为预设的支持属性类型;若所述属性类型为所述支持属性类型,则判断所述属性类型对应的类是否为Object-C类;若所述属性类型对应的类为Object-C类,则获取所述属性类型对应的类名,判断所述属性类型对应的类名是否为所述工具类的子类;若所述属性类型对应的类名不是所述工具类的子类,则判断所述属性类型对应的类名是否为Object-C基础类;当所述属性类型的类不是Object-C类,或者所述属性类型对应的类名是所述工具类的子类,或者所述属性类型对应的类名是所述Object-C基础类时,获取所述属性对应的属性名。
为实现上述目的,根据本发明实施例的另一方面,提供了一种将JSON对象转换为模型对象的方法。
本发明实施例的一种将JSON对象转换为模型对象的方法,包括:获取JSON对象的键值的类型,判断所述键值的类型是否为字典;若所述键值的类型为字典,则获取预定义的模型对象的属性,以查找与所述JSON对象的键名相关联的属性类型;获取所述JSON对象的原始键值,若所述原始键值为空,则创建所述属性类型对应类的实例,以将所述实例的属性名设置为所述键名,将所述属性名对应的属性值设置为预设键值。
可选地,所述方法还包括:判断所述键值的类型是否为数组,若所述键值的类型为数组且所述数组的数组元素被标记为可JSON化的模型对象,则创建所述模型对象的实例;将所述实例的属性名设置为所述键名,将所述实例的属性值设置为所述数组元素的值。
可选地,所述获取所述JSON对象的原始键值,包括:判断所述属性类型是否为所述模型对象的子类,若所述属性类型是所述模型对象的子类,则获取所述JSON对象的原始键值;所述方法还包括:判断所述原始键值是否为空,若所述原始键值不为空,则将所述原始键值更新为预设键值;将所述属性名设置为所述键名,将所述属性值设置为所述原始键值。
为实现上述目的,根据本发明实施例的另一方面,提供了一种将模型对象转换为JSON对象的装置。
本发明实施例的一种将模型对象转换为JSON对象的装置,包括:第一获取模块,用于获取预定义的模型对象的属性,以得到所述属性对应的属性名;第二获取模块,用于从实例化后的模型对象中获取所述属性名对应的属性值;生成模块,用于判断所述属性值是否为预定义的工具类的实例,若所述属性值为所述工具类的实例,则通过递归算法生成JSON对象,其中,所述工具类为所述模型对象的父类。
可选地,所述装置还包括:第一处理模块,用于判断所述属性值是否为数组,若所述属性值为数组且所述数组的数组元素被标记为可JSON化的模型对象,则判断所述数组元素是否为所述模型对象的实例;以及当所述数组的数组元素为所述模型对象的实例时,将所述数组元素转换为所述JSON对象。
可选地,所述装置还包括:标记判断模块,用于将所述数组元素标记为可JSON化的模型对象;以及将所述模型对象的类名以及所述属性名作为键,将所述数组元素作为值进行存储,以判断所述数组的数组元素是否被标记为可JSON化的模型对象。
可选地,所述第一获取模块,还用于:获取所述属性对应的属性类型,判断所述属性类型是否为预设的支持属性类型;若所述属性类型为所述支持属性类型,则判断所述属性类型对应的类是否为Object-C类;若所述属性类型对应的类为Object-C类,则获取所述属性类型对应的类名,判断所述属性类型对应的类名是否为所述工具类的子类;若所述属性类型对应的类名不是所述工具类的子类,则判断所述属性类型对应的类名是否为Object-C基础类;以及当所述属性类型的类不是Object-C类,或者所述属性类型对应的类名是所述工具类的子类,或者所述属性类型对应的类名是所述Object-C基础类时,获取所述属性对应的属性名。
为实现上述目的,根据本发明实施例的另一方面,提供了一种将JSON对象转换为模型对象的装置。
本发明实施例的一种将JSON对象转换为模型对象的装置,包括:判断模块,用于获取JSON对象的键值的类型,判断所述键值的类型是否为字典;查找模块,用于若所述键值的类型为字典,则获取预定义的模型对象的属性,以查找与所述JSON对象的键名相关联的属性类型;第一设置模块,用于获取所述JSON对象的原始键值,若所述原始键值为空,则创建所述属性类型对应类的实例,以将所述实例的属性名设置为所述键名,将所述属性名对应的属性值设置为预设键值。
可选地,所述装置还包括:第二处理模块,用于判断所述键值的类型是否为数组,若所述键值的类型为数组且所述数组的数组元素被标记为可JSON化的模型对象,则创建所述模型对象的实例;以及将所述实例的属性名设置为所述键名,将所述实例的属性值设置为所述数组元素的值。
可选地,所述第一设置模块,还用于:判断所述属性类型是否为所述模型对象的子类,若所述属性类型是所述模型对象的子类,则获取所述JSON对象的原始键值;所述装置还包括:第二设置模块,用于判断所述原始键值是否为空,若所述原始键值不为空,则将所述原始键值更新为预设键值;以及将所述属性名设置为所述键名,将所述属性值设置为所述原始键值。
为实现上述目的,根据本发明实施例的再一方面,提供了一种电子设备。
本发明实施例的一种电子设备,包括:一个或多个处理器;存储装置,用于存储一个或多个程序,当所述一个或多个程序被所述一个或多个处理器执行,使得所述一个或多个处理器实现本发明实施例的一种将模型对象转换为JSON对象的方法。
为实现上述目的,根据本发明实施例的再一方面,提供了一种计算机可读介质。
本发明实施例的一种计算机可读介质,其上存储有计算机程序,所述程序被处理器执行时实现本发明实施例的一种将模型对象转换为JSON对象的方法。
为实现上述目的,根据本发明实施例的再一方面,提供了一种电子设备。
本发明实施例的一种电子设备,包括:一个或多个处理器;存储装置,用于存储一个或多个程序,当所述一个或多个程序被所述一个或多个处理器执行,使得所述一个或多个处理器实现本发明实施例的一种将JSON对象转换为模型对象的方法。
为实现上述目的,根据本发明实施例的再一方面,提供了一种计算机可读介质。
本发明实施例的一种计算机可读介质,其上存储有计算机程序,所述程序被处理器执行时实现本发明实施例的一种将JSON对象转换为模型对象的方法。
上述发明中的一个实施例具有如下优点或有益效果:通过获取模型对象的属性值后,判断属性值的类型,如果所述属性值为预定义的工具类的实例,则使用递归算法生成JSON对象,实现了嵌套有其他模型对象的模型对象到JSON对象的转换;当属性值为数组,并且数组元素被标记为可JSON化的模型对象且为模型对象的实例时,将数组元素转换为JSON对象,实现了数组元素为自定义的模型对象到JSON对象的转换;预先将数组元素标记为可JSON化的模型对象,并以键值对进行存储,方便确定数组是否满足进行转换的条件;设置获取属性名的条件,以在满足该条件的情况下执行属性名的获取;通过当JSON对象的键值的类型为字典时,查找与JSON对象的键名相关联的属性类型,以创建属性类型的实例,进而将实例的属性名设置为键名、属性值设置为键值,实现了键值类型为字典的JSON对象到模型对象的转换;当键值为数组且数组元素被标记为可JSON化的模型对象时,创建所述模型对象的实例,以实现键值类型为数组的JSON对象到模型对象的转换;设置获取原始键值的条件,在满足该条件的情况下执行原始键值的获取,以在获取的原始键值不为空时,更新原始键值。
上述的非惯用的可选方式所具有的进一步效果将在下文中结合具体实施方式加以说明。
附图说明
附图用于更好地理解本发明,不构成对本发明的不当限定。其中:
图1是根据本发明实施例的将模型对象转换为JSON对象的方法的主要步骤的示意图;
图2是根据本发明实施例的将JSON对象转换为模型对象的方法的主要步骤的示意图;
图3是根据本发明实施例的将模型对象转换为JSON对象的方法的主要流程示意图;
图4是根据本发明实施例的将模型对象转换为JSON对象的结果示意图;
图5是根据本发明实施例的将JSON对象转换为模型对象的方法的主要流程示意图;
图6是根据本发明实施例的将JSON对象转换为模型对象的结果示意图;
图7是根据本发明实施例的将模型对象转换为JSON对象的装置的主要模块的示意图;
图8是根据本发明实施例的将JSON对象转换为模型对象的装置的主要模块的示意图;
图9是本发明实施例可以应用于其中的示例性***架构图;
图10是适用于来实现本发明实施例的电子设备的计算机装置的结构示意图。
具体实施方式
以下结合附图对本发明的示范性实施例做出说明,其中包括本发明实施例的各种细节以助于理解,应当将它们认为仅仅是示范性的。因此,本领域普通技术人员应当认识到,可以对这里描述的实施例做出各种改变和修改,而不会背离本发明的范围和精神。同样,为了清楚和简明,以下的描述中省略了对公知功能和结构的描述。
图1是根据本发明实施例的将模型对象转换为JSON对象的方法的主要步骤的示意图。本发明实施例中涉及到的字典和数组均为Object-C语言中的数据类型。如图1所示,本发明实施例的将模型对象转换为JSON对象的方法,主要包括如下步骤:
步骤S101:获取预定义的模型对象的属性,以得到所述属性对应的属性名。所述模型对象是自定义的工具类或者该工具类的子类,包括一个或者多个属性,所述属性有一种或者多种属性类型,比如int、long、NSString、自定义的模型对象或者其子类、数组且数组元素为自定义的模型对象等。该步骤中,调用class_copyPropertyList接口,获取所述模型对象的属性;之后,调用property_getName接口,获取所述属性对应的属性名。
步骤S102:从实例化后的模型对象中获取所述属性名对应的属性值。对所述模型对象进行实例化处理,之后调用-[NSObjectdictionaryWithValuesForKeys:]接口,即可获取所述属性名对应的属性值,后续需判断该属性值的是工具类的实例,还是数组,还是其他类型,以根据判断结果进行不同处理。
步骤S103:判断所述属性值是否为预定义的工具类的实例,若所述属性值为所述工具类的实例,则通过递归算法生成JSON对象。实施例中,所述工具类为JDPayJSONModel类。JDPayJSONModel类继承自NSObject类,内部仅280行左右的代码,该类提供一个-[JDPayJSONModel toJSONDictionary]接口,用于将模型对象转换JSON对象;提供一个可JSON化数组属性标记接口+[JDPayJSONModelsetJSONAbleElementClass:forArrayProperty:],用于标记某一数组类属性内的元素是可JSON化的JDPayJSONModel类型;通过重载其父类的-[NSObject setValue:forKey:]接口实现JSON对象到模型对象的转换,通过调用-[NSObject setValuesForKeysWithDictionary:]接口实现JSON对象到模型对象的转换。用户使用时只需创建JDPayJSONModel类的子类,即可实现模型对象与JSON对象的互换。该步骤用于判断所述属性值是否嵌套有模型对象,如果是,则通过使用递归算法把嵌套的模型对象转换为JSON对象。之后,可以键值对的形式,将所述JSON对象存储到字典中。通过步骤S101至步骤S103实现了将嵌套的模型对象一一转换为JSON对象的目的。
图2是根据本发明实施例的将JSON对象转换为模型对象的方法的主要步骤的示意图。如图2所示,本发明实施例的将JSON对象转换为模型对象的方法,主要包括如下步骤:
步骤S201:获取JSON对象的键值的类型,判断所述键值的类型是否为字典。其中,JSON对象是指Object-C语言中的字典数据类型,JSON对象可以通过API转化为标准的JSON字符串数据。JSON对象的数据格式为:键名/键值对,键名/键值对包括字段名称和对应的值,字段名称和值均在双引号中,且两者之间用“:”隔开,比如"firstName":"John"。键值的类型可以是字符串、数值、字典、数组等。调用-[NSObject isKindOfClass:]接口,获取预先定义的JSON对象的键值的类型。
步骤S202:若所述键值的类型为字典,则获取预定义的模型对象的属性,以查找与所述JSON对象的键名相关联的属性类型。调用class_copyPropertyList接口,获取模型对象的所有属性,实施例中所述模型对象为JDPayJSONModel类。通过枚举查找到与所述键名相同的模型对象的属性名,该属性名对应的属性类型即为与所述键名相关联的属性类型。
步骤S203:获取所述JSON对象的原始键值,若所述原始键值为空,则创建所述属性类型对应类的实例,以将所述实例的属性名设置为所述键名,将所述属性名对应的属性值设置为预设键值。该步骤,首先判断所述属性类型是否为所述模型对象的子类,若所述属性类型是所述模型对象的子类,则调用valueForKey接口获取所述JSON对象的原始键值。之后,判断所述原始键值是否为空(nil),如果是则创建所述属性类型对应类的实例,调用setValue:forKey:接口将属性名设置为所述JSON对象的键名,将与所述属性名对应的属性值设置为预设键值。
图3是根据本发明实施例的将模型对象转换为JSON对象的方法的主要流程示意图。如图3所示,将模型对象转换为JSON对象的方法,核心依赖的接口是-[JDPayJSONModeltoJSONDictionary],该接口的实现主要包括如下步骤:
步骤S301:定义模型对象、所述模型对象不支持的属性类型和支持的基础类。实施例中,所述模型对象为JDPayJSONModel类或者其子类,JDPaJSONModel类是NSObject的子类,模型对象中包括一个或者多个属性,所述属性有一种或者多种属性类型。实施例中,使用Object-C语言定义了模型对象:OJSONModel类,本例中定义的OJSONModel类是JDPayJSONModel类的子类,具体为:
@interface OJSONModel:JDPayJSONModel
@property(nonatomic,strong)NSString*string;
@property(nonatomic,strong)NSMutableString*mutableString;
@property(nonatomic,strong)NSNumber*number;
@property(nonatomic,strong)NSDecimalNumber*decimalNumber;
@property(nonatomic,strong)NSDictionary*dictionary;
@property(nonatomic,strong)NSDictionary*mutableDictionary;
@property(nonatomic,strong)NSArray*array;
@property(nonatomic,strong)NSMutableArray*mutableArray;
@end
在初始化时,定义所述模型对象不支持的属性类型前缀,比如,指针:"T^"、id类型:"T@,"、结构体:"T{"、union类型:"T("等。同样地,在初始化时,定义所述模型对象支持的Object-C基础类,比如NSString.class(字符串类)、NSMutableString.class(可变字符串类)、NSDecimalNumber.class(十进制数字类)、NSNumber.class(数字类)、NSMutableDictionary.class(可变字典类)、NSDictionary.class(不可变字典类)、NSArray.class(不可变数组类)、NSMutableArray.class(可变数组类)等。
步骤S302:获取所述模型对象的属性。实施例中,通过调用class_copyPropertyList接口,获取所述模型对象的所有属性。所述属性即为定义的所述模型对象中的@property语句,即OJSONModel类包括八个属性。
步骤S303:判断是否有未枚举的属性,如果是,则执行步骤S304;如果不是,则结束本流程。将步骤S302获取的所有属性放置到一个属性数组中,以遍历属性数组中的每个属性。
步骤S304:枚举所述属性,执行步骤S305。枚举即遍历属性数组中的每个属性。
步骤S305:获取当前属性的属性类型。实施例中,通过调用property_getAttributes接口获取属性类型。所述属性类型对应于OJSONModel类中的NSString(字符串)、NSMutableString(可变字符串)、NSNumber(数字)、NSDecimalNumber(十进制数字)、NSDictionary(字典)和NSArray(数组)。
步骤S306:判断当前属性类型是否为预设的支持属性类型,如果是,则执行步骤S307;如果不是,则丢弃对应的属性,执行步骤S304。获取到当前属性的属性类型后,将该属性类型作为当前属性类型,之后将所述当前属性类型与定义的不支持的属性类型进行比对,如果获取到的属性类型为不支持属性类型,比如指针等,则丢弃该属性;如果不支持的属性类型中没有当前属性类型,则该属性类型为支持属性类型。
步骤S307:判断所述当前属性类型对应的类是否为Object-C类,如果是,则获取所述当前属性类型对应的类名,执行步骤S308;如果不是,则执行步骤S310。该步骤即判断当前属性类型所归属的属性前缀是否为"T@",如果是,则该当前属性类型对应的类为Object-C类。获取到属性类型后,可以调用NSClassFromString接口生成属性类型对应的类。
步骤S308:判断所述当前属性类型对应的类是否是JDPayJSONModel类的子类,如果是,则执行步骤S310;如果不是,则执行步骤S309。实施例中,基于获取的当前属性类型对应的类名,通过调用+[Class(BOOL)isSubclassOfClass:(Class)aClass]接口来判断当前属性类型对应的类是否是JDPayJSONModel类的子类。
步骤S309:判断所述当前属性类型对应的类是否为支持的Object-C基础类,如果是,则执行步骤S310;如果不是,则执行步骤S304。查找步骤S301中定义好的基础类中是否存在所述当前属性类型对应的类名,如果存在,则所述当前属性类型对应的类为支持的基础类。
步骤S310:获取所述当前属性的属性名。实施例中,通过调用property_getName接口获取属性名,所述属性名对应于实施例的OJSONModel类中的string、mutableString、number、decimalNumber、dictionary、mutableDictionary、array和mutableArray。
步骤S311:从实例化后的模型对象中获取当前属性名对应的属性值。获取到当前属性的属性名后,将该属性名作为当前属性名。实施例中,通过调用[NSObjectdictionaryWithValuesForKeys:]接口获取属性值。
步骤S312:判断当前属性值是否为JDPayJSONModel类的实例,如果是,则执行步骤S313;如果不是,执行步骤S315。获取到当前属性的值后,将该值作为当前属性值。
步骤S313:生成所述当前属性对应的JSON对象。所述JSON对象为通过调用+[NSJSONSerialization isValidJSONObject:]接口得到的返回值为YES的Object-C对象,即该对象可以使用iOS***的API转化为标准的JSON字符串数据,但是对象必须是字典并且字典的Key必须是字符串,字典内的元素必须是NSString、NSMutableString、NSNumber、NSDecimalNumber、NSDictionary、NSMutableDictionary(可变字典)、NSArray、和NSMutableArray(可变数组)。实施例中,使用递归算法调用toJSONDictionary接口生成当前属性对应的JSON对象。在计算机领域中,递归是指一种通过重复将问题分解为同类的子问题而解决问题的方法。这里的同类问题就是在不同对象上调用相同的toJSONDictionary接口,以把嵌套的模型对象(JDPayJSONModel)转化为JSON对象。
步骤S314:判断生成的所述JSON对象是否为nil,如果是,则执行步骤S304;如果不是,则执行步骤S324。其中,nil是一种类型,它只有一个值nil,表示无值,它的主要功能是用于区别其他任何值。
步骤S315:判断所述当前属性值是否是数组且所述数组的数组元素被标记为可JSON化的JDPayJSONModel类或者其子类,如果是,则执行步骤S316;如果不是,则执行步骤S324。实施例中,通过调用[value isKindOfClass:NSArray.class]接口判断所述当前属性值是否为数组。在初始化时,调用setJSONAbleElementClass:(Class)elementClassforArrayProperty:(NSString*)propertyName接口将数组类型的属性内的元素标记为可JSON化的JDPayJSONModel类或者其子类。标记时将当前类名和属性名作为键,将传入的elementClass作为值,保存到全局字典里。当在某个对象上调用setValue:V forKey:K的时候,当前对象的类名是已知的,属性名是K,即有了类名和属性名,之后到全局字典查找就可以知道该数组元素是否是被标记的。
步骤S316:创建JSON对象数组。实施例中,JSON对象数组可以用newValues表示,newValues用于存放步骤S315的数组中每个元素生成的JSON对象。
步骤S317:判断所述数组是否有未枚举的数组元素,如果有,则执行步骤S318;否则,执行步骤S323。
步骤S318:枚举所述数组的数组元素,执行步骤S319。
步骤S319:判断当前数组元素是否为被标记类的实例,如果是,则执行步骤S320;如果不是,则执行步骤S317。所述被标记类为数组元素被标记为的可JSON化的JDPayJSONModel类或者其子类。
步骤S320:生成所述当前数组元素对应的JSON对象。实施例中,调用-[JDPayJSONModel toJSONDictionary]接口生成当前数组元素对应的JSON对象。
步骤S321:判断生成的所述JSON对象是否为nil,如果是,则执行步骤S317;如果不是,则执行步骤S322。
步骤S322:将生成的所述JSON对象加入JSON对象数组,执行步骤S317。即将当前数组元素对应的JSON对象添加到newValues中。
步骤S323:判断JSON对象数组是否为空,如果是,则执行步骤S304;如果不是,则执行步骤S324。即判断JSON对象数组newValues是否为空。
步骤S324:以键值对的形式,将所述JSON对象存储到字典中。所述字典为一种数据结构,包括很多内置函数,字典是一种键值对的数据容器,键值对(key:value)用冒号“:”分割,键值对之间用逗“,”分割,整个字典包括在花括号“{}”中,且键和值两者一一对应。该步骤以Key(键名)-Value(键值)的形式,将所有JSON对象存储到字典中。
实施例中,定义了两个模型对象,分别是OJSONModel类和PSONModel类,这两个模型对象均是JDPayJSONModel类的子类。OJSONModel类的定义如前所述,PSONModel类定义为:
@interface PJSONModel:JDPayJSONModel
@property(nonatomic,assign)char c;
@property(nonatomic,assign)int intValue;
@property(nonatomic,assign)short shortValue;
@property(nonatomic,assign)long longValue;
@property(nonatomic,assign)long long longLongValue;
@property(nonatomic,assign)unsigned char uc;
@property(nonatomic,assign)unsigned int unsignedIntValue;
@property(nonatomic,assign)unsigned short unsignedShortValue;
@property(nonatomic,assign)unsigned long unsignedLongValue;
@property(nonatomic,assign)unsigned long long unsignedLongLongValue;
@property(nonatomic,assign)float floatValue;
@property(nonatomic,assign)double doubleValue;
@property(nonatomic,assign)BOOL boolValue;
//定义名称为oms的成员变量,其类型为数组、且数组元素是自定义的OJSONModel模型对象
@property(nonatomic,strong)NSArray<OJSONModel*>*oms;
//定义名称为om的成员变量,其类型为自定义的OJSONModel模型对象
@property(nonatomic,strong)OJSONModel*om;
@end
将JSONModel类和PSONModel类分别进行实例化。实例化结果为:
//标记oms数组内的元素是可JSON化的OJSONModel类
[PJSONModel setJSONAbleElementClass:OJSONModel.classforArrayProperty:@"oms"];
//om
OJSONModel*om=[OJSONModel new];
om.string=@"string";
om.mutableString=[NSMutableString stringWithString:@"mutableString"];
om.number=[NSNumber numberWithInteger:11];
om.decimalNumber=[NSDecimalNumber decimalNumberWithString:@"12"];
om.dictionary=@{@"key":@"value"};
om.mutableDictionary=[NSMutableDictionary dictionaryWithDictionary:om.dictionary];
om.array=@[@1,@2,@3];
om.mutableArray=[NSMutableArray arrayWithArray:om.array];
//pm
PJSONModel*pm=[PJSONModel new];
pm.c='c';
pm.intValue=1;
pm.shortValue=2;
pm.longValue=3;
pm.longLongValue=4;
pm.uc='C';
pm.unsignedIntValue=5u;
pm.unsignedShortValue=6u;
pm.unsignedLongValue=7u;
pm.unsignedLongLongValue=8u;
pm.floatValue=9.f;
pm.doubleValue=10.0;
pm.boolValue=YES;
pm.oms=@[om];
pm.om=om;
//调用toJSONDictionary接口将模型对象pm转换为JSON对象pmd
NSDictionary*pmd=[pm toJSONDictionary];
图4是根据本发明实施例的将模型对象转换为JSON对象的结果示意图。如图4所示,根据上述定义和实施例化后的JSONModel类和PSONModel类,按照本发明实施例的将模型对象转换为JSON对象的方法,最终将模型对象pm转换成了JSON对象pmd。该转换过程支持所有原数据类型(char,int,short,long,long long,unsigned x,double,float,CGFloat,NSInteger,NSUInteger等),支持Object-C基础数据类型(NSString,NSMutableString,NSNumber,NSDecimalNumber,NSDictionary,NSMutableDictionary,NSArray,NSMutableArray),支持Object-C模型对象嵌套,而且支持数组(NSArray)内的Object-C模型对象。
通过本发明实施例的将模型对象转换为JSON对象的方法可以看出,通过获取模型对象的属性值后,判断属性值的类型,如果所述属性值为预定义的工具类的实例,则使用递归算法生成JSON对象,实现了嵌套有其他模型对象的模型对象到JSON对象的转换;当属性值为数组,并且数组元素被标记为可JSON化的模型对象且为模型对象的实例时,将数组元素转换为JSON对象,实现了数组元素为自定义的模型对象到JSON对象的转换;预先将数组元素标记为可JSON化的模型对象,并以键值对进行存储,方便确定数组是否满足进行转换的条件;设置获取属性名的条件,以在满足该条件的情况下执行属性名的获取。
图5是根据本发明实施例的将JSON对象转换为模型对象的方法的主要流程示意图。如图5所示,将JSON对象转换为模型对象的方法,核心依赖的接口是-[NSObjectsetValue:forKey:],主要包括如下步骤:
步骤S501:获取JSON对象的键值的类型。实施例中,通过调用-[NSObjectisKindOfClass:]接口获取预先设置的JSON对象的键值V的类型,该键值V的类型可能是字符串、数值、字典、数组等。
步骤S502:判断所述键值的类型是否为字典,如果是字典,则执行步骤S503;如果不是字典,则执行步骤S512。实施例中,通过调用[V isKindOfClass:NSDictionary.class]接口判断所述键值的类型是否为字典。
步骤S504:获取定义的模型对象的属性,枚举查找与当前键名相关联的属性。获取模型对象的所有属性,通过枚举查找到与当前键名相同的模型对象的属性名,该属性名对应的属性即为与当前键名相关联的属性。
步骤S505:判断是否查找到了与当前键名相关联的属性,如果是,则执行步骤S506;如果不是,则执行步骤S519。
步骤S506:获取与所述当前键名相关联的属性的属性类型。
步骤S507:判断所述属性类型对应的类是否是所述JDPayJSONModel类的子类,如果是,则执行步骤S508;如果不是,执行步骤S519。比如,定义的PJSONModel类的属性类型包括OJSONModel,OJSONModel类是PJSONModel的父类JDPayJSONModel类的子类。
步骤S508:获取所述当前键名的原始键值。实施例中,调用valueForKey接口获取所述当前键名的原始键值OV。
步骤S509:判断所述原始键值是否nil,如果是,则执行步骤S510;如果不是,则执行步骤S511。
步骤S510:创建所述属性类型对应类的实例,并初始化,执行步骤S512。创建所述属性类型对应类的实例TI,并调用-[NSObjectsetValuesForKeysWithDictionary:]接口用键值V初始化TI,对应于PJSONModel*pmo=[[PJSONModel alloc]initWithDictionary:pmd];语句。
步骤S511:更新所述原始键值,执行步骤S512。实施例中,调用-[NSObjectsetValuesForKeysWithDictionary:]接口,将所述原始键值由OV更新为V。
步骤S512:为与所述当前键名相关联的属性设置属性值,结束本流程。实施例中,调用setValue:forKey:接口将属性名设置为所述键名K,将与所述当前键名相关联的属性的属性值对应设置为TI或者OV,之后将当前键名标记为已处理。
步骤S513:判断所述键值的类型是否为数组,如果是数组,则执行步骤S514;如果不是数组,则执行步骤S519。实施例中,通过调用[V isKindOfClass:NSArray.class]接口判断所述键值的类型是否为数组。
步骤S514:判断所述数组内的数组元素是否被标记为可JSON化的JDPayJSONModel类或者其子类,如果是,则执行步骤S515;如果不是,则执行步骤S519。在进行初始化时,调用setJSONAbleElementClass:(Class)elementClass forArrayProperty:(NSString*)propertyName接口将数组类型的属性内的元素标记为可JSON化的JDPayJSONModel类或者其子类。标记时将当前类名和属性名作为键,将传入的elementClass作为值,并保存到全局字典里。当在某个对象上调用setValue:VforKey:K的时候,当前对象的类名是已知的,属性名是K,即有了类名和属性名,之后到全局字典查找就可以知道该数组元素是否是被标记的。
步骤S515:创建新数组。所述新数组newValues1用于存放后续V表示的数组内JSON对象转换的Object-C模型对象的实例OI。
步骤S516:枚举所述数组的数组元素,创建所述模型对象的实例,初始化所述实例并添加到所述新数组。实施例中,枚举数组类型的键值V中的数组元素E,创建JDPayJSONModel类的实例OI,调用-[NSObject setValuesForKeysWithDictionary:]接口用数组元素E初始化OI并加入到新数组newValues1中。
步骤S517:判断所述新数组是否为空,如果不是,则执行步骤S518;如果是,则执行步骤S519。即判断新数组newValues1是否为空。
步骤S518:将所述新数组赋值给所述当前键名对应的键值,执行步骤S519。将新数组newValues1赋值给键值V。
步骤S519:设置所述属性的属性名为所述键名,属性值为所述键值,结束本流程。调用-[NSObject setValue:forKey:]接口,将所述属性名设置为所述JSON对象的键名,将所述属性名对应的属性值设置为所述JSON对象的键值。
实施例中,同样定义了两个模型对象,分别是OJSONModel类和PSONModel类,这两个模型对象均是JDPayJSONModel类的子类。OJSONModel类和PSONModel类的定义如前所述。将JSONModel类和PSONModel类分别进行实例化。实例化结果如前所述,之后通过PJSONModel*pmo=[[PJSONModel alloc]initWithDictionary:pmd]语句,将JSON对象转换为了模型对象。
图6是根据本发明实施例的将JSON对象转换为模型对象的结果示意图。如图6所示,按照本发明实施例的将JSON对象转换为模型对象的方法,最终将JSON对象pmd转换成了模型对象pmo。该转换过程同样支持所有原数据类型(char,int,short,long,long long,unsignedx,double,float,CGFloat,NSInteger,NSUInteger等),支持Object-C基础数据类型(NSString,NSMutableString,NSNumber,NSDecimalNumber,NSDictionary,NSMutableDictionary,NSArray,NSMutableArray),支持Object-C模型对象嵌套,而且支持数组(NSArray)内的Object-C模型对象。
通过本发明实施例的将JSON对象转换为模型对象的方法可以看出,通过当JSON对象的键值的类型为字典时,查找与JSON对象的键名相关联的属性类型,以创建属性类型的实例,进而将实例的属性名设置为键名、属性值设置为键值,实现了键值类型为字典的JSON对象到模型对象的转换;当键值为数组且数组元素被标记为可JSON化的模型对象时,创建所述模型对象的实例,以实现键值类型为数组的JSON对象到模型对象的转换;设置获取原始键值的条件,在满足该条件的情况下执行原始键值的获取,以在获取的原始键值不为空时,更新原始键值。
图7是根据本发明实施例的将模型对象转换为JSON对象的装置的主要模块的示意图。如图7所示,本发明实施例的将模型对象转换为JSON对象的装置700,主要包括:
第一获取模块701,用于获取预定义的模型对象的属性,以得到所述属性对应的属性名。所述模型对象是自定义的工具类或者该工具类的子类,包括一个或者多个属性,所述属性有一种或者多种属性类型,比如int、long、NSString、自定义的模型对象或者其子类、数组且数组元素为自定义的模型对象等。该步骤中,调用class_copyPropertyList接口,获取所述模型对象的属性;之后,调用property_getName接口,获取所述属性对应的属性名。
第二获取模块702,用于从实例化后的模型对象中获取所述属性名对应的属性值。对所述模型对象进行实例化处理,之后调用-[NSObjectdictionaryWithValuesForKeys:]接口,即可获取所述属性名对应的属性值,后续需判断该属性值的是工具类的实例,还是数组,还是其他类型,以根据判断结果进行不同处理。
生成模块703,用于判断所述属性值是否为预定义的工具类的实例,若所述属性值为所述工具类的实例,则通过递归算法生成JSON对象,其中,所述工具类为所述模型对象的父类。实施例中,所述工具类为JDPayJSONModel类。JDPayJSONModel类继承自NSObject类,内部仅280行左右的代码,该类提供一个-[JDPayJSONModeltoJSONDictionary]接口,用于将模型对象转换JSON对象;提供一个可JSON化数组属性标记接口+[JDPayJSONModelsetJSONAbleElementClass:forArrayProperty:],用于标记某一数组类属性内的元素是可JSON化的JDPayJSONModel类型;通过重载其父类的-[NSObject setValue:forKey:]接口实现JSON对象到模型对象的转换,通过调用-[NSObject setValuesForKeysWithDictionary:]接口实现JSON对象到模型对象的转换。用户使用时只需创建JDPayJSONModel类的子类,即可实现模型对象与JSON对象的互换。该步骤用于判断所述属性值是否嵌套有模型对象,如果是,则通过使用递归算法把嵌套的模型对象转换为JSON对象。之后,可以键值对的形式,将所述JSON对象存储到字典中。通过上述模块实现了将嵌套的模型对象一一转换为JSON对象的目的。
另外,本发明实施例的将模型对象转换为JSON对象的装置700还可以包括:第一处理模块和标记判断模块(图7中未示出)。其中,所述第一处理模块,用于判断所述属性值是否为数组,若所述属性值为数组且所述数组的数组元素被标记为可JSON化的模型对象,则判断所述数组元素是否为所述模型对象的实例;以及当所述数组的数组元素为所述模型对象的实例时,将所述数组元素转换为所述JSON对象。所述标记判断模块,用于将所述数组元素标记为可JSON化的模型对象;将所述模型对象的类名以及所述属性名作为键,将所述数组元素作为值进行存储,以判断所述数组的数组元素是否被标记为可JSON化的模型对象。
从以上描述可以看出,通过获取模型对象的属性值后,判断属性值的类型,如果所述属性值为预定义的工具类的实例,则使用递归算法生成JSON对象,实现了嵌套有其他模型对象的模型对象到JSON对象的转换;当属性值为数组,并且数组元素被标记为可JSON化的模型对象且为模型对象的实例时,将数组元素转换为JSON对象,实现了数组元素为自定义的模型对象到JSON对象的转换;预先将数组元素标记为可JSON化的模型对象,并以键值对进行存储,方便确定数组是否满足进行转换的条件;设置获取属性名的条件,以在满足该条件的情况下执行属性名的获取。
图8是根据本发明实施例的将JSON对象转换为模型对象的装置的主要模块的示意图。如图8所示,本发明实施例的将JSON对象转换为模型对象的装置800,主要包括:
判断模块801,用于获取JSON对象的键值的类型,判断所述键值的类型是否为字典。其中,JSON对象是指Object-C语言中的字典数据类型,JSON对象可以通过API转化为标准的JSON字符串数据。JSON对象的数据格式为:键名/键值对,键名/键值对包括字段名称和对应的值,字段名称和值均在双引号中,且两者之间用“:”隔开,比如"firstName":"John"。键值的类型可以是字符串、数值、字典、数组等。调用-[NSObject isKindOfClass:]接口,获取预先定义的JSON对象的键值的类型。
查找模块802,用于若所述键值的类型为字典,则获取预定义的模型对象的属性,以查找与所述JSON对象的键名相关联的属性类型。调用class_copyPropertyList接口,获取模型对象的所有属性,实施例中所述模型对象为JDPayJSONModel类。通过枚举查找到与所述键名相同的模型对象的属性名,该属性名对应的属性类型即为与所述键名相关联的属性类型。
第一设置模块803,用于获取所述JSON对象的原始键值,若所述原始键值为空,则创建所述属性类型对应类的实例,以将所述实例的属性名设置为所述键名,将所述属性名对应的属性值设置为预设键值。该模块,首先判断所述属性类型是否为所述模型对象的子类,若所述属性类型是所述模型对象的子类,则调用valueForKey接口获取所述JSON对象的原始键值。之后,判断所述原始键值是否为空(nil),如果是则创建所述属性类型对应类的实例,调用setValue:forKey:接口将属性名设置为所述JSON对象的键名,将与所述属性名对应的属性值设置为预设键值。
另外,本发明实施例的将JSON对象转换为模型对象的装置800还可以包括:第二处理模块和第二设置模块(图8中未示出)。其中,所述第二处理模块,用于判断所述键值的类型是否为数组,若所述键值的类型为数组且所述数组的数组元素被标记为可JSON化的模型对象,则创建所述模型对象的实例;以及将所述实例的属性名设置为所述键名,将所述实例的属性值设置为所述数组元素的值。所述第二设置模块,用于判断所述原始键值是否为空,若所述原始键值不为空,则将所述原始键值更新为预设键值;以及将所述属性名设置为所述键名,将所述属性值设置为所述原始键值。
从以上描述可以看出,通过当JSON对象的键值的类型为字典时,查找与JSON对象的键名相关联的属性类型,以创建属性类型的实例,进而将实例的属性名设置为键名、属性值设置为键值,实现了键值类型为字典的JSON对象到模型对象的转换;当键值为数组且数组元素被标记为可JSON化的模型对象时,创建所述模型对象的实例,以实现键值类型为数组的JSON对象到模型对象的转换;设置获取原始键值的条件,在满足该条件的情况下执行原始键值的获取,以在获取的原始键值不为空时,更新原始键值。
图9示出了可以应用本发明实施例的模型对象与JSON对象互转的方法或模型对象与JSON对象互转的装置的示例性***架构900。
如图9所示,***架构900可以包括终端设备901、902、903,网络904和服务器905。网络904用以在终端设备901、902、903和服务器905之间提供通信链路的介质。网络904可以包括各种连接类型,例如有线、无线通信链路或者光纤电缆等等。
用户可以使用终端设备901、902、903通过网络904与服务器905交互,以接收或发送消息等。终端设备901、902、903上可以安装有各种通讯客户端应用,例如购物类应用、网页浏览器应用、搜索类应用、即时通信工具、邮箱客户端、社交平台软件等。
终端设备901、902、903可以是具有显示屏并且支持网页浏览的各种电子设备,包括但不限于智能手机、平板电脑、膝上型便携计算机和台式计算机等等。
服务器905可以是提供各种服务的服务器,例如对管理员利用终端设备901、902、903所发送的预定义的模型对象或者JSON对象进行分析的后台管理服务器。后台管理服务器可以对接收到的模型对象或者JSON对象进行分析等处理,并将处理结果(例如模型对象与JSON对象之间的转换结果)反馈给终端设备。
需要说明的是,本申请实施例所提供的模型对象与JSON对象互转的方法一般由服务器905执行,相应地,模型对象与JSON对象互转的装置一般设置于服务器905中。
应该理解,图9中的终端设备、网络和服务器的数目仅仅是示意性的。根据实现需要,可以具有任意数目的终端设备、网络和服务器。
根据本发明的实施例,本发明还提供了一种电子设备和一种计算机可读介质。
本发明的电子设备包括:一个或多个处理器;存储装置,用于存储一个或多个程序,当所述一个或多个程序被所述一个或多个处理器执行,使得所述一个或多个处理器实现本发明实施例的一种模型对象与JSON对象互转的方法。
本发明的计算机可读介质,其上存储有计算机程序,所述程序被处理器执行时实现本发明实施例的一种模型对象与JSON对象互转的方法。
下面参考图10,其示出了适用于来实现本发明实施例的电子设备的计算机***1000的结构示意图。图10示出的电子设备仅仅是一个示例,不应对本发明实施例的功能和使用范围带来任何限制。
如图10所示,计算机***1000包括中央处理单元(CPU)1001,其可以根据存储在只读存储器(ROM)1002中的程序或者从存储部分1008加载到随机访问存储器(RAM)1003中的程序而执行各种适当的动作和处理。在RAM 1003中,还存储有计算机***1000操作所需的各种程序和数据。CPU 1001、ROM 1002以及RAM 1003通过总线1004彼此相连。输入/输出(I/O)接口1005也连接至总线1004。
以下部件连接至I/O接口1005:包括键盘、鼠标等的输入部分1006;包括诸如阴极射线管(CRT)、液晶显示器(LCD)等以及扬声器等的输出部分1007;包括硬盘等的存储部分1008;以及包括诸如LAN卡、调制解调器等的网络接口卡的通信部分1009。通信部分1009经由诸如因特网的网络执行通信处理。驱动器1010也根据需要连接至I/O接口1005。可拆卸介质1011,诸如磁盘、光盘、磁光盘、半导体存储器等等,根据需要安装在驱动器1010上,以便于从其上读出的计算机程序根据需要被安装入存储部分1008。
特别地,根据本发明公开的实施例,上文主要步骤图描述的过程可以被实现为计算机软件程序。例如,本公开的实施例包括一种计算机程序产品,其包括承载在计算机可读介质上的计算机程序,该计算机程序包含用于执行主要步骤图所示的方法的程序代码。在这样的实施例中,该计算机程序可以通过通信部分1009从网络上被下载和安装,和/或从可拆卸介质1011被安装。在该计算机程序被中央处理单元(CPU)1001执行时,执行本发明的***中限定的上述功能。
需要说明的是,本发明所示的计算机可读介质可以是计算机可读信号介质或者计算机可读存储介质或者是上述两者的任意组合。计算机可读存储介质例如可以是——但不限于——电、磁、光、电磁、红外线、或半导体的***、装置或器件,或者任意以上的组合。计算机可读存储介质的更具体的例子可以包括但不限于:具有一个或多个导线的电连接、便携式计算机磁盘、硬盘、随机访问存储器(RAM)、只读存储器(ROM)、可擦式可编程只读存储器(EPROM或闪存)、光纤、便携式紧凑磁盘只读存储器(CD-ROM)、光存储器件、磁存储器件、或者上述的任意合适的组合。在本发明中,计算机可读存储介质可以是任何包含或存储程序的有形介质,该程序可以被指令执行***、装置或者器件使用或者与其结合使用。而在本发明中,计算机可读的信号介质可以包括在基带中或者作为载波一部分传播的数据信号,其中承载了计算机可读的程序代码。这种传播的数据信号可以采用多种形式,包括但不限于电磁信号、光信号或上述的任意合适的组合。计算机可读的信号介质还可以是计算机可读存储介质以外的任何计算机可读介质,该计算机可读介质可以发送、传播或者传输用于由指令执行***、装置或者器件使用或者与其结合使用的程序。计算机可读介质上包含的程序代码可以用任何适当的介质传输,包括但不限于:无线、电线、光缆、RF等等,或者上述的任意合适的组合。
附图中的流程图和框图,图示了按照本发明各种实施例的***、方法和计算机程序产品的可能实现的体系架构、功能和操作。在这点上,流程图或框图中的每个方框可以代表一个模块、程序段、或代码的一部分,上述模块、程序段、或代码的一部分包含一个或多个用于实现规定的逻辑功能的可执行指令。也应当注意,在有些作为替换的实现中,方框中所标注的功能也可以以不同于附图中所标注的顺序发生。例如,两个接连地表示的方框实际上可以基本并行地执行,它们有时也可以按相反的顺序执行,这依所涉及的功能而定。也要注意的是,框图或流程图中的每个方框、以及框图或流程图中的方框的组合,可以用执行规定的功能或操作的专用的基于硬件的***来实现,或者可以用专用硬件与计算机指令的组合来实现。
描述于本发明实施例中所涉及到的模块可以通过软件的方式实现,也可以通过硬件的方式来实现。所描述的模块也可以设置在处理器中,例如,可以描述为:一种处理器包括第一获取模块、第二获取模块、生成模块、判断模块、查找模块和设置模块。其中,这些模块的名称在某种情况下并不构成对该模块本身的限定,例如,第一获取模块还可以被描述为“获取预定义的模型对象的属性,以得到所述属性对应的属性名的模块”。
作为另一方面,本发明还提供了一种计算机可读介质,该计算机可读介质可以是上述实施例中描述的设备中所包含的;也可以是单独存在,而未装配入该设备中。上述计算机可读介质承载有一个或者多个程序,当上述一个或者多个程序被一个该设备执行时,使得该设备包括:获取预定义的模型对象的属性,以得到所述属性对应的属性名;从实例化后的模型对象中获取所述属性名对应的属性值;判断所述属性值是否为预定义的工具类的实例,若所述属性值为所述工具类的实例,则通过递归算法生成JSON对象,其中,所述工具类为所述模型对象的父类。以及包括获取JSON对象的键值的类型,判断所述键值的类型是否为字典;若所述键值的类型为字典,则获取预定义的模型对象的属性,以查找与所述JSON对象的键名相关联的属性类型;创建所述属性类型对应类的实例,以将所述实例的属性名设置为所述键名,将所述属性名对应的属性值设置为所述键值。
从以上描述可以看出,通过获取模型对象的属性值后,判断属性值的类型,如果所述属性值为预定义的工具类的实例,则使用递归算法生成JSON对象,实现了嵌套有其他模型对象的模型对象到JSON对象的转换;当属性值为数组,并且数组元素被标记为可JSON化的模型对象且为模型对象的实例时,将数组元素转换为JSON对象,实现了数组元素为自定义的模型对象到JSON对象的转换;预先将数组元素标记为可JSON化的模型对象,并以键值对进行存储,方便确定数组是否满足进行转换的条件;设置获取属性名的条件,以在满足该条件的情况下执行属性名的获取;通过当JSON对象的键值的类型为字典时,查找与JSON对象的键名相关联的属性类型,以创建属性类型的实例,进而将实例的属性名设置为键名、属性值设置为键值,实现了键值类型为字典的JSON对象到模型对象的转换;当键值为数组且数组元素被标记为可JSON化的模型对象时,创建所述模型对象的实例,以实现键值类型为数组的JSON对象到模型对象的转换;设置获取原始键值的条件,在满足该条件的情况下执行原始键值的获取,以在获取的原始键值不为空时,更新原始键值。
上述产品可执行本发明实施例所提供的方法,具备执行方法相应的功能模块和有益效果。未在本实施例中详尽描述的技术细节,可参见本发明实施例所提供的方法。
上述具体实施方式,并不构成对本发明保护范围的限制。本领域技术人员应该明白的是,取决于设计要求和其他因素,可以发生各种各样的修改、组合、子组合和替代。任何在本发明的精神和原则之内所作的修改、等同替换和改进等,均应包含在本发明保护范围之内。