【问题标题】:iOS JSON serialization for NSObject-based classes基于 NSObject 的类的 iOS JSON 序列化
【发布时间】:2012-05-17 21:43:04
【问题描述】:

我想对我自己的自定义类进行 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。我需要一些可以使用对象进行序列化和反序列化的东西。

非常感谢。

【问题讨论】:

标签: objective-c ios json serialization nsobject


【解决方案1】:

这是一个棘手的问题,因为您可以放入 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 安全对象中所需的条件语句的属性类型。

【讨论】:

  • 感谢您,也感谢 Ricard。我确实设法在您最初的指导下构建了一个解决方案。
  • 干得好!希望不会被苹果封杀。
  • 下面 Malcolm 提出的库已经为您做到了。
【解决方案2】:

现在您可以使用JSONModel 轻松解决此问题。 JSONModel 是一个基于 Class 对对象进行一般序列化/反序列化的库。你甚至可以对intshortfloat 等属性使用非nsobject。它还可以满足嵌套复杂的 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]);

【讨论】:

  • 一个优雅的解决方案。非常感谢。
【解决方案3】:

也许这可以帮助JLObjectStrip

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

【讨论】:

    【解决方案4】:

    试试这个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];
    ...
    

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 2013-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-22
        相关资源
        最近更新 更多