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

相关文章

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

Java第二阶段---09类和对象---第三节 构造方法

第三节 构造方法 1.概念 构造方法是一种特殊的方法,主要用于创建对象以及完成对象的属性初始化操作。构造方法不能被对象调用。 2.语法 //[]中内容可有可无 访问修饰符 类名([参数列表]){ } 3.示例 public class Car {     //车特征(属性)     public String name;//车名   可以直接拿来用 说明它有初始值     pu

HTML5自定义属性对象Dataset

原文转自HTML5自定义属性对象Dataset简介 一、html5 自定义属性介绍 之前翻译的“你必须知道的28个HTML5特征、窍门和技术”一文中对于HTML5中自定义合法属性data-已经做过些介绍,就是在HTML5中我们可以使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放,例如我们要在一个文字按钮上存放相对应的id: <a href="javascript:" d

php中json_decode()和json_encode()

1.json_decode() json_decode (PHP 5 >= 5.2.0, PECL json >= 1.2.0) json_decode — 对 JSON 格式的字符串进行编码 说明 mixed json_decode ( string $json [, bool $assoc ] ) 接受一个 JSON 格式的字符串并且把它转换为 PHP 变量 参数 json

PHP7扩展开发之对象方式使用lib库

前言 上一篇文章,我们使用的是函数方式调用lib库。这篇文章我们将使用对象的方式调用lib库。调用代码如下: <?php $hello = new hello(); $result = $hello->get(); var_dump($result); ?> 我们将在扩展中实现hello类。hello类中将依赖lib库。 代码 基础代码 这个扩展,我们将在say扩展上增加相关代码。sa

struts2中的json返回指定的多个参数

要返回指定的多个参数,就必须在struts.xml中的配置如下: <action name="goodsType_*" class="goodsTypeAction" method="{1}"> <!-- 查询商品类别信息==分页 --> <result type="json" name="goodsType_findPgae"> <!--在这一行进行指定,其中lis是一个List集合,但

hibernate修改数据库已有的对象【简化操作】

陈科肇 直接上代码: /*** 更新新的数据并并未修改旧的数据* @param oldEntity 数据库存在的实体* @param newEntity 更改后的实体* @throws IllegalAccessException * @throws IllegalArgumentException */public void updateNew(T oldEntity,T newEntity

特殊JSON解析

一般的与后台交互;都会涉及到接口数据的获取;而这里的数据一般情况就是JSON 了;JSON 解析起来方便;而且数据量也较小一些;所以JSON在接口数据返回中是个很不错的选择。 下面简单说下JSON解析过程中的一些案例: 这里我用到了三方的架包:fastjson-1.1.39.jar 架包 可以在我的博客中找到下载;或者网上找下 很多的; 这里主要就是映射  关系了;这就要求:实体类的名称和

类和对象的定义和调用演示(C++)

我习惯把类的定义放在头文件中 Student.h #define _CRT_SECURE_NO_WARNINGS#include <string>using namespace std;class student{public:char m_name[25];int m_age;int m_score;char* get_name(){return m_name;}int set_name