iOS:从NSObject类序列化/反序列化复杂JSON

iOS:从NSObject类序列化/反序列化复杂JSON,ios,objective-c,json,generics,jsonkit,Ios,Objective C,Json,Generics,Jsonkit,有人知道如何序列化基于NSObject类的嵌套JSON吗?对简单JSON进行了序列化讨论,但它不够通用,无法满足复杂的嵌套JSON 假设这是JSON的结果: { "accounting" : [{ "firstName" : "John", "lastName" : "Doe", "age" : 23 }, { "firstName" : "Mary",

有人知道如何序列化基于NSObject类的嵌套JSON吗?对简单JSON进行了序列化讨论,但它不够通用,无法满足复杂的嵌套JSON

假设这是JSON的结果:

{ "accounting" : [{ "firstName" : "John",  
                    "lastName"  : "Doe",
                    "age"       : 23 },

                  { "firstName" : "Mary",  
                    "lastName"  : "Smith",
                    "age"       : 32 }
                              ],                            
  "sales"      : [{ "firstName" : "Sally", 
                    "lastName"  : "Green",
                    "age"       : 27 },

                  { "firstName" : "Jim",   
                    "lastName"  : "Galley",
                    "age"       : 41 }
                  ]}
本课程:

@interface Person : NSObject{}
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSNumber *age;
@end

@interface Department : NSObject{}
@property (nonatomic, strong) NSMutableArray *accounting; //contain Person class
@property (nonatomic, strong) NSMutableArray *sales; //contain Person class
@end
如何基于类对它们进行序列化/反序列化

编辑

目前,我能够基于任何类别生成如下有效负载:

NSMutableDictionary *Payload = [self serialize:objClass];

但它不适合嵌套的复杂JSON。有谁有更好的解决办法吗?对于C#Cate,基于对象类进行序列化/反序列化。我想在NSObject的基础上复制同样的东西

您必须提前知道您将反序列化什么类型的对象。在本例中,您将反序列化到一个
NSDictionary
,该字典有两个属性:“accounting”和“sales”。这些属性中的每一个都是
NSArray
的实例。数组将有
NSDictionary
的实例

因为您知道这些对象的真正含义,所以一旦将JSON反序列化为本机对象,就可以从反序列化的对象中创建新的类实例。例如:

JSONDecoder decoder = [[JSONDecoder alloc] init];
NSObject notJSON = [decoder objectWithData:jsonData];
// where jsonData is an NSData representation of your JSON
[decoder release];

Person person1 = (Person)[notJSON objectForKey:@"accounting"][0];

给出这个示例,您应该能够推断出更通用的反序列化程序。也就是说,您希望通过循环数据来创建“未知”通用对象到“已知”特定对象的深度副本。

最后,我们可以使用。这是迄今为止最好的方法。JSONModel是一个基于类对对象进行一般序列化/反序列化的库。您甚至可以使用非基于nsobject的属性,如
int
short
float
。它还可以处理嵌套的复杂JSON

1)反序列化示例。通过参考上述示例,在头文件中:

#import "JSONModel.h"

@interface Person : JSONModel 
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSNumber *age;
@end

@protocol Person;

@interface Department : JSONModel
@property (nonatomic, strong) NSMutableArray<Person> *accounting;
@property (nonatomic, strong) NSMutableArray<Person> *sales;
@end
2)序列化示例。在实现文件中:

#import "JSONModelLib.h"
#import "myJSONClass.h"

NSString *responseJSON = /*from example*/;
Department *department = [[Department alloc] initWithString:responseJSON error:&err];
if (!err)
{
    for (Person *person in department.accounting) {

        NSLog(@"%@", person.firstName);
        NSLog(@"%@", person.lastName);
        NSLog(@"%@", person.age);         
    }

    for (Person *person in department.sales) {

        NSLog(@"%@", person.firstName);
        NSLog(@"%@", person.lastName);
        NSLog(@"%@", person.age);         
    }
}
#import "JSONModelLib.h"
#import "myJSONClass.h"

Department *department = [[Department alloc] init];

Person *personAcc1 = [[Person alloc] init];
personAcc1.firstName = @"Uee";
personAcc1.lastName = @"Bae";
personAcc1.age = [NSNumber numberWithInt:22];
[department.accounting addOject:personAcc1];

Person *personSales1 = [[Person alloc] init];
personSales1.firstName = @"Sara";
personSales1.lastName = @"Jung";
personSales1.age = [NSNumber numberWithInt:20];
[department.sales addOject:personSales1];

NSLog(@"%@", [department toJSONString]);
这是序列化示例的NSLog结果:

{ "accounting" : [{ "firstName" : "Uee",  
                    "lastName"  : "Bae",
                    "age"       : 22 }
                 ],                            
  "sales"      : [{ "firstName" : "Sara", 
                    "lastName"  : "Jung",
                    "age"       : 20 }
                  ]}
也许这个能帮上忙。 它可以帮助您用一行代码轻松地将JSON字符串或JSON对象与数据模型匹配起来

...
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];
...

对不起,这不是通用的。正如我所说的,正如你在参考资料中所说的,在这方面完全通用是不可能的。JSONKit已经在解码为通用本机对象。这取决于你去了解他们到底是什么。如果您不能要求JSON(通过某些属性)告诉您,那么您必须期望一种已知的格式。我已经为此创建了一个更好的解决方案,但它仍然不能满足嵌套JSON的要求。一层嵌套的JSON没有问题。有了它,我可以传递任何我想要序列化/反序列化的类。现在我打电话给任何人,如果他们有任何想法如何做这件复杂的事情JSON@MalcolmMashmallow-为什么“嵌套JSON”更难?一次只处理一个层。因为您知道将从json填充模型,所以您可以包括一个
initWithDictionary:
方法,该方法将映射保留到各个模型。是的,
initWithDictionary
是一种很好的初始化方法,它的优点是,它也可以用于一般情况,即对象是响应“本地”需求而初始化的。特别是使用新的
@{…}
表示法,创建一个包含所有参数的字典很容易(如果JSON没有提供现成的字典)。此外,如果您使用JSONSerialization选项提供可变对象,您可以修改传入的字典,例如,更改一个键名,或者添加JSON中可能缺少的其他PARM。一种方法不是——只需继续处理NSDictionary对象,而不是自定义类。这通常比您想象的更好。您可以始终向类添加方法
initWithJSONObject:error:
(例如,通过类别)。@CouchDeveloper-
initWithDictionary
可能更通用。(如果值得的话,您可以包含
错误:
parm。)@HotLicks我更喜欢在类别中使用更独特的名称,甚至可能使用前缀。但是我同意,作为类
initWithDictionary
中的init方法是一个不错的选择。问题是,如果你养成了使用
initWithDictionary
的习惯,你就不必担心将JSON读入对象。它基本上就是工作的——将字典传递给init例程,它尽可能地处理,并创建辅助对象,并在适当的时候调用它们的
initWithDictionary
方法。只要JSON与对象结构大致匹配,就可以了。