基于NSObject的类的iOS JSON序列化

时间:2012-05-09 11:17:08

标签: objective-c ios json serialization nsobject

我想JSON序列化我自己的自定义类。我在Objective-C / iOS5工作。 我想要做以下事情:

Person* person = [self getPerson ]; // Any custom object, NOT based on NSDictionary
NSString* jsonRepresentation = [JsonWriter stringWithObject:person ];
Person* clone = [JsonReader objectFromJson: jsonRepresentation withClass:[Person Class]];

似乎NSJSONSerialization(以及其他几个库)要求'person'类基于NSDictionary等。我想要一些能够序列化我想要定义的任何自定义对象(在合理范围内)。

让我们假设Person.h看起来像这样:

#import <Foundation/Foundation.h>
@interface Person : NSObject 
@property NSString* firstname;
@property NSString* surname;
@end

我希望实例生成的JSON看起来类似于以下内容:

{"firstname":"Jenson","surname":"Button"}

我的应用使用ARC。我需要能够使用对象进行序列化和反序列化的东西。

非常感谢。

5 个答案:

答案 0 :(得分:23)

这是一个棘手的问题,因为你可以放入JSON的唯一数据是直接简单的对象(想想NSString,NSArray,NSNumber ......),而不是自定义类或标量类型。为什么?如果不构建各种条件语句来将所有这些数据类型包装到这些类型的对象中,解决方案就像:

//at the top…
#import <objC/runtime.h>

    NSMutableDictionary *muteDictionary = [NSMutableDictionary dictionary];

    id YourClass = objc_getClass("YOURCLASSNAME");
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList(YourClass, &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        SEL propertySelector = NSSelectorFromString(propertyName);
        if ([classInstance respondsToSelector:propertySelector]) {
            [muteDictionary setValue:[classInstance performSelector:propertySelector] forKey:propertyName];
        }
    }
    NSError *jsonError = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:muteDictionary options:0 error:&jsonError];

这很棘手,不过是因为我之前所说的。如果你有任何标量类型或自定义对象,整个事情就会崩溃。如果让这样的事情变得非常关键,我建议投入时间并查看Ricard的链接,这些链接允许您查看属性类型,这些属性类型将有助于将值包装到NSDictionary安全对象中所需的条件语句。

答案 1 :(得分:16)

现在,您可以使用JSONModel轻松解决此问题。 JSONModel是一个基于Class一般序列化/反序列化对象的库。您甚至可以使用非基于nsobject的属性,例如intshortfloat。它还可以满足嵌套复杂的JSON。

反序列化示例。通过引用您的示例,在头文件中:

#import "JSONModel.h"

@interface Person : JSONModel 
@property (nonatomic, strong) NSString* firstname;
@property (nonatomic, strong) NSString* surname;
@end

在实施文件中:

#import "JSONModelLib.h"
#import "yourPersonClass.h"

NSString *responseJSON = /*from somewhere*/;
Person *person = [[Person alloc] initWithString:responseJSON error:&err];
if (!err)
{
   NSLog(@"%@  %@", person.firstname, person.surname):
}

序列化示例。在实现文件中:

#import "JSONModelLib.h"
#import "yourPersonClass.h"

Person *person = [[Person alloc] init];
person.firstname = @"Jenson";
person.surname = @"Uee";

NSLog(@"%@", [person toJSONString]);

答案 2 :(得分:1)

也许这可以帮助JLObjectStrip

它与jacob所说的相同,但它甚至迭代到了类的属性。这将为您提供字典/数组,然后使用sbjson / jsonkit或者您更喜欢构建json字符串。

答案 3 :(得分:0)

试试这个BWJSONMatcher

它既简单又方便。

...
NSString *jsonString = @"{your-json-string}";
YourValueObject *dataModel = [YourValueObject fromJSONString:jsonString];

NSDictionary *jsonObject = @{your-json-object};
YourValueObject *dataModel = [YourValueObject fromJSONObject:jsonObject];
...
YourValueObject *dataModel = instance-of-your-value-object;
NSString *jsonString = [dataModel toJSONString];
NSDictionary *jsonObject = [dataModel toJSONObject];
...

答案 4 :(得分:0)

我为我的对象做的是我有一个名为&#34; toDict&#34;返回一个nsdictionary。在这个方法中,我将我需要/想要的所有属性设置到字典中,例如

[user setObject:self.first_name forKey:@"first_name"];
[user setObject:self.last_name forKey:@"last_name"];
[user setObject:self.email forKey:@"email"];