iOS: 把对象直接转化成NSDictionary或JSON_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > iOS: 把对象直接转化成NSDictionary或JSON

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

 2013/9/17 2:46:27  _Mgen  博客园  我要评论(0)
  • 摘要:目录1.使用2.实现3.下载和代码 返回目录1.使用实现的结果就是可以把任何对象转化成字典或者字典对应的JSON。字典的数据就是来自对象的属性名称和属性值。而且是多层的,也就是说如果对象的某个属性值是另一个对象,数组,或者字典,该值都会被转换成另一个字典。这个类型名称是PrintObject,它的所有方法都是静态的:@interfacePrintObject:NSObject//通过对象返回一个NSDictionary,键是属性名称,值是属性值。+(NSDictionary*
  • 标签:iOS JSON JS

目录

  • 1. 使用
  • 2. 实现
  • 3. 下载和代码

 

返回目录

1. 使用

实现的结果就是可以把任何对象转化成字典或者字典对应的JSON。字典的数据就是来自对象的属性名称和属性值 。而且是多层的,也就是说如果对象的某个属性值是另一个对象,数组,或者字典,该值都会被转换成另一个字典。

这个类型名称是PrintObject,它的所有方法都是静态的:

@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, 这个类型如下定义:

@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类型创建一个复杂的对象,其中包含非对象属性,对象属性,还有包含对象的数组和字典。代码如下:

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变量)的字典:

NSDictionary *dic = [PrintObject getObjectData:main];

NSLog(@"%@", dic);

 

输出:

{

    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数据:

NSData *jsonData = [PrintObject getJSON:main options:NSJSONWritingPrettyPrinted error:nil];

NSString *jsonText = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

NSLog(@"%@", jsonText);

 

结果:

{

  "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

#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

#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

发表评论
用户名: 匿名