本文主要是介绍iOS:把对象直接转化成NSDictionary或JSON,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
iOS:把对象直接转化成NSDictionary或JSON
1. 使用
实现的结果就是可以把任何对象转化成字典或者字典对应的JSON。字典的数据就是来自对象的属性名称和属性值 。而且是多层的,也就是说如果对象的某个属性值是另一个对象,数组,或者字典,该值都会被转换成另一个字典。
这个类型名称是PrintObject,它的所有方法都是静态的:
1 2 3 4 5 6 7 8 9 10 11 | @interface PrintObject : NSObject //通过对象返回一个NSDictionary,键是属性名称,值是属性值。 + (NSDictionary*)getObjectData:(id)obj; //将getObjectData方法返回的NSDictionary转化成JSON + (NSData*)getJSON:(id)obj options:(NSJSONWritingOptions)options error:(NSError**)error; //直接通过NSLog输出getObjectData方法返回的NSDictionary + (void)print:(id)obj; @end |
举个例子,比如用来保存数据的类型是MyData, 这个类型如下定义:
1 2 3 4 5 6 7 8 9 | @interface MyData : NSObject @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) NSString *nullString; @property (nonatomic) int age; @property (nonatomic) BOOL male; @property (nonatomic, strong) MyData *objProp; @property (nonatomic, strong) NSArray *arrProp; @property (nonatomic, strong) NSDictionary *dicProp; @end |
然后通过MyData类型创建一个复杂的对象,其中包含非对象属性,对象属性,还有包含对象的数组和字典。代码如下:
1 2 3 4 5 6 7 8 9 10 11 | MyData *main = [[MyData alloc] init]; main.name = @ "mgen" ; main.age = 22; MyData *childOfChild = [[MyData alloc] init]; childOfChild.name = @ "child of child" ; childOfChild.age = -443; MyData *child = [[MyData alloc] init]; child.name = @ "child" ; child.arrProp = @[@ "test" , @234, @[@123, @ "array in array" , childOfChild]]; main.objProp = child; main.dicProp = @{@ "中文Key" : @3.444444, @ "object" : childOfChild}; |
OK,接着使用PrintObject类型输出这个MyData对象(上面的main变量)的字典:
1 2 | NSDictionary *dic = [PrintObject getObjectData:main]; NSLog(@ "%@" , dic); |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | { age = 22; arrProp = "<null>" ; dicProp = { object = { age = "-443" ; arrProp = "<null>" ; dicProp = "<null>" ; male = 0; name = "child of child" ; nullString = "<null>" ; objProp = "<null>" ; }; "\U4e2d\U6587Key" = "3.444444" ; }; male = 0; name = mgen; nullString = "<null>" ; objProp = { age = 0; arrProp = ( test, 234, ( 123, "array in array" , { age = "-443" ; arrProp = "<null>" ; dicProp = "<null>" ; male = 0; name = "child of child" ; nullString = "<null>" ; objProp = "<null>" ; } ) ); dicProp = "<null>" ; male = 0; name = child; nullString = "<null>" ; objProp = "<null>" ; }; } |
也可以输出这个对象的JSON数据
1 2 3 | NSData *jsonData = [PrintObject getJSON:main options:NSJSONWritingPrettyPrinted error:nil]; NSString *jsonText = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSLog(@ "%@" , jsonText); |
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | { "arrProp" : null , "name" : "mgen" , "age" : 22, "objProp" : { "arrProp" : [ "test" , 234, [ 123, "array in array" , { "arrProp" : null , "name" : "child of child" , "age" : -443, "objProp" : null , "male" : 0, "nullString" : null , "dicProp" : null } ] ], "name" : "child" , "age" : 0, "objProp" : null , "male" : 0, "nullString" : null , "dicProp" : null }, "male" : 0, "nullString" : null , "dicProp" : { "中文Key" : 3.444444, "object" : { "arrProp" : null , "name" : "child of child" , "age" : -443, "objProp" : null , "male" : 0, "nullString" : null , "dicProp" : null } } } |
2. 实现
在实现上,属性的枚举是通过定义在<objc/runtime.h>中的class_copyPropertyList方法实现。其次,属性值的获取是通过KVC中的valueForKey方法,这个方法同时可以将非对象类型(如BOOL, int等)转换成NSNumber。
接着就是对数组,字典和对象类型值的嵌套处理,所有值就可以获取出来了。
至于JSON,如果正确获取了NSDictionary后,直接使用iOS 5后的NSJSONSerialization类型的dataWithJSONObject方法就可以返回包含JSON字符串的NSData对象了。
3. 下载和代码
源代码下载 下载页面
注意:链接是微软SkyDrive页面,下载时请用浏览器直接下载,用某些下载工具可能无法下载
源代码环境:Xcode 4.6.3
PrintObject.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | #import <Foundation/Foundation.h> @interface PrintObject : NSObject //通过对象返回一个NSDictionary,键是属性名称,值是属性值。 + (NSDictionary*)getObjectData:(id)obj; //将getObjectData方法返回的NSDictionary转化成JSON + (NSData*)getJSON:(id)obj options:(NSJSONWritingOptions)options error:(NSError**)error; //直接通过NSLog输出getObjectData方法返回的NSDictionary + (void)print:(id)obj; @end |
PrintObject.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | #import "PrintObject.h" #import <objc/runtime.h> @implementation PrintObject + (NSDictionary*)getObjectData:(id)obj { NSMutableDictionary *dic = [NSMutableDictionary dictionary]; unsigned int propsCount; objc_property_t *props = class_copyPropertyList([obj class], &propsCount); for (int i = 0;i < propsCount; i++) { objc_property_t prop = props[i]; NSString *propName = [NSString stringWithUTF8String:property_getName(prop)]; id value = [obj valueForKey:propName]; if (value == nil) { value = [NSNull null ]; } else { value = [self getObjectInternal:value]; } [dic setObject:value forKey:propName]; } return dic; } + (void)print:(id)obj { NSLog(@ "%@" , [self getObjectData:obj]); } + (NSData*)getJSON:(id)obj options:(NSJSONWritingOptions)options error:(NSError**)error { return [NSJSONSerialization dataWithJSONObject:[self getObjectData:obj] options:options error:error]; } + (id)getObjectInternal:(id)obj { if ([obj isKindOfClass:[NSString class]] || [obj isKindOfClass:[NSNumber class]] || [obj isKindOfClass:[NSNull class]]) { return obj; } if ([obj isKindOfClass:[NSArray class]]) { NSArray *objarr = obj; NSMutableArray *arr = [NSMutableArray arrayWithCapacity:objarr.count]; for (int i = 0;i < objarr.count; i++) { [arr setObject:[self getObjectInternal:[objarr objectAtIndex:i]] atIndexedSubscript:i]; } return arr; } if ([obj isKindOfClass:[NSDictionary class]]) { NSDictionary *objdic = obj; NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[objdic count]]; for (NSString *key in objdic.allKeys) { [dic setObject:[self getObjectInternal:[objdic objectForKey:key]] forKey:key]; } return dic; } return [self getObjectData:obj]; } @end |
这篇关于iOS:把对象直接转化成NSDictionary或JSON的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!