18

我想对我自己的自定义类进行 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 (和其他几个库)要求“人”类基于 NSDictionary 等。我想要一些可以序列化我想要定义的任何自定义对象的东西(在合理范围内)。

让我们想象一下 Person.h 看起来像这样:

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

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

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

我的应用程序使用 ARC。我需要一些可以使用对象进行序列化和反序列化的东西。

非常感谢。

4

5 回答 5

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 安全对象中的条件语句的属性类型。

于 2012-05-09T14:17:26.583 回答
16

现在您可以使用JSONModel轻松解决这个问题。JSONModel 是一个基于 Class 对对象进行一般序列化/反序列化的库。您甚至可以使用基于非 nsobject 的属性,例如int,shortfloat. 它还可以满足嵌套复杂的 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]);
于 2013-05-27T09:37:14.817 回答
1

也许这可以帮助JLObjectStrip

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

于 2013-04-29T09:49:21.767 回答
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];
...
于 2015-10-29T03:44:15.313 回答
0

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

[user setObject:self.first_name forKey:@"first_name"];
[user setObject:self.last_name forKey:@"last_name"];
[user setObject:self.email forKey:@"email"];
于 2016-11-25T04:28:37.143 回答