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

2024-01-08 20:48

本文主要是介绍iOS:把对象直接转化成NSDictionary或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人喜欢 


这篇关于iOS:把对象直接转化成NSDictionary或JSON的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/584773

相关文章

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

JSON Web Token在登陆中的使用过程

《JSONWebToken在登陆中的使用过程》:本文主要介绍JSONWebToken在登陆中的使用过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录JWT 介绍微服务架构中的 JWT 使用结合微服务网关的 JWT 验证1. 用户登录,生成 JWT2. 自定义过滤

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

python dict转换成json格式的实现

《pythondict转换成json格式的实现》本文主要介绍了pythondict转换成json格式的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下... 一开始你变成字典格式data = [ { 'a' : 1, 'b' : 2, 'c编程' : 3,

Java实现XML与JSON的互相转换详解

《Java实现XML与JSON的互相转换详解》这篇文章主要为大家详细介绍了如何使用Java实现XML与JSON的互相转换,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. XML转jsON1.1 代码目的1.2 代码实现2. JSON转XML3. JSON转XML并输出成指定的

Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

《Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursion)的问题及解决方案》使用Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursi... 目录解决方案‌1. 使用 @jsonIgnore 忽略一个方向的引用2. 使用 @JsonManagedR

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3