iOS:把对象直接转化成NSDictionary或JSON

简介: iOS:把对象直接转化成NSDictionary或JSONMgen|2013-09-18 10:48|15515次浏览|IOS(296)开发(190)应用(36)对象(1)Dictionary(1)01. 使用实现的结果就是可以把任何对象转化成字典或者字典对应的JSON。


iOS:把对象直接转化成NSDictionary或JSON

Mgen|2013-09-18 10:48|15515次浏览| IOS(296)开发(190)应用(36)对象(1)Dictionary(1) 0

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
来自:cnblogs
分享到微信
0人喜欢 


目录
相关文章
|
3月前
|
JSON JavaScript 前端开发
JavaScript实现字符串转json对象的方法
JavaScript实现字符串转json对象的方法
|
1月前
|
JSON 前端开发 JavaScript
json字符串如何转为list对象?
json字符串如何转为list对象?
64 7
|
1月前
|
JSON JavaScript 前端开发
js如何格式化一个JSON对象?
js如何格式化一个JSON对象?
43 3
|
2月前
|
XML JSON JavaScript
JSON对象的stringify()和parse()方法使用
本文阐述了JSON对象的`stringify()`和`parse()`方法的用法,包括如何将JavaScript对象转换为JSON字符串,以及如何将JSON字符串解析回JavaScript对象,并讨论了转换过程中需要注意的事项。
JSON对象的stringify()和parse()方法使用
|
2月前
|
JSON 前端开发 中间件
React读取properties配置文件转化为json对象并使用在url地址中
本文介绍了如何在React项目中读取properties配置文件,将其内容转化为JSON对象,并在请求URL地址时使用这些配置。文章详细说明了异步读取文件、处理字符串转换为JSON对象的过程,并提供了一个封装函数,用于在发起请求前动态生成配置化的URL地址。
51 1
|
4月前
|
存储 JSON 测试技术
python中json和类对象的相互转化
针对python中类对象和json的相关转化问题, 本文介绍了4种方式,涉及了三个非常强大的python库jsonpickle、attrs和cattrs、pydantic,但是这些库的功能并未涉及太深。在工作中,遇到实际的问题时,可以根据这几种方法,灵活选取。 再回到结构化测试数据的构造,当需要对数据进行建模时,也就是赋予数据业务含义,pydantic应该是首选,目前(2024.7.1)来看,pydantic的生态非常活跃,各种基于pydantic的工具也非常多,建议尝试。
|
5月前
|
JSON Java fastjson
老程序员分享:java对象转json
老程序员分享:java对象转json
168 3
|
4月前
|
存储 JSON Java
Java对象转换为JSON字符串
在Java开发中,常需将数据对象转换为JSON存储,如使用Fastjson库。要将Java对象转为JSON,可调用`JSON.toJSONString(obj)`;反向转换则用`JSON.parseObject(str, Class)`。
|
4月前
|
JSON Java 数据格式
前后端数据交换,JSON基础语法和JSON数据和Java对象转换,最快的对象转换,JSON{““}字符串如何写User{id=1,username=‘zhangsan‘,password=‘123‘}
前后端数据交换,JSON基础语法和JSON数据和Java对象转换,最快的对象转换,JSON{““}字符串如何写User{id=1,username=‘zhangsan‘,password=‘123‘}
|
5月前
|
JSON 运维 Serverless
函数计算产品使用问题之无法返回JSON对象,一般是什么导致的
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。