iOS: serializar / deserializar el complejo JSON genéricamente desde la clase NSObject

¿Alguien tiene idea de cómo serializar JSON nested basado en la clase NSObject? Existe una discusión para serializar JSON simple aquí , pero no es lo suficientemente genérico para abastecer JSON nested complejo.

Imagina que este es el resultado de 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 } ]} 

De esta clase:

 @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 

¿Cómo serializarlos / deserializarlos según la clase genéricamente?

EDITAR

Actualmente puedo generar una carga útil como esta basada en cualquier clase:

 NSMutableDictionary *Payload = [self serialize:objClass]; 

Pero no atiende el complejo JSON nested. Alguien tiene una mejor solución para esto? Esta biblioteca para C # provee serialización / deserialización basada en la clase de objeto. Quiero reproducir algo igual basado en NSObject

Finalmente podemos resolver este problema fácilmente usando JSONModel . Este es el mejor método hasta ahora. JSONModel es una biblioteca que serializa / deserializa genéricamente su objeto en función de la clase. Incluso puede usar non-nsobject basado en propiedades como int , short y float . También puede atender el JSON nested complejo.

1) Deserializar el ejemplo . Al hacer referencia al ejemplo anterior, en el archivo de encabezado:

 #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 *accounting; @property (nonatomic, strong) NSMutableArray *sales; @end 

en archivo de implementación:

 #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); } } 

2) Ejemplo de serialización . En archivo de implementación:

 #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]); 

Y este es el resultado de NSLog del ejemplo de serialización:

 { "accounting" : [{ "firstName" : "Uee", "lastName" : "Bae", "age" : 22 } ], "sales" : [{ "firstName" : "Sara", "lastName" : "Jung", "age" : 20 } ]} 

Debes saber de antemano qué tipo de objeto estarás deserializando. En este caso, va a deserializar a un NSDictionary que tiene dos propiedades: “contabilidad” y “ventas”. Cada una de estas propiedades será una instancia de NSArray . Las matrices tendrán instancias de NSDictionary .

Como sabes qué son realmente cada uno de estos objetos, una vez que hayas deserializado el JSON en objetos nativos, puedes crear nuevas instancias de tus clases a partir de los objetos deserializados. Por ejemplo:

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

Dado este ejemplo, debería poder extrapolar a un deserializador más genérico. Es decir, desea recorrer sus datos para crear una copia profunda de su objeto genérico “desconocido” a un objeto específico “conocido”.

Tal vez este pueda ayudar a BWJSONMatcher . Le ayuda a emparejar fácilmente una cadena JSON o un objeto JSON con su modelo de datos con una línea de código.

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