objective c - example - iOS JSON serialización para clases basadas en NSObject
jsonserialization.jsonobject swift 4 (5)
Me gustaría JSON-serializar mis propias clases personalizadas. Estoy trabajando en Objective-C / iOS5. Me gustaría algo para hacer lo siguiente:
Person* person = [self getPerson ]; // Any custom object, NOT based on NSDictionary
NSString* jsonRepresentation = [JsonWriter stringWithObject:person ];
Person* clone = [JsonReader objectFromJson: jsonRepresentation withClass:[Person Class]];
Parece que la serialización NSJSONS (y varias otras bibliotecas) requieren que la clase "persona" se base en NSDictionary, etc. Quiero algo que serialice cualquier objeto personalizado que me importe definir (dentro de lo razonable).
Imaginemos que Person.h se parece a esto:
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString* firstname;
@property NSString* surname;
@end
Me gustaría que el JSON generado para una instancia se pareciera a lo siguiente:
{"firstname":"Jenson","surname":"Button"}
Mi aplicación utiliza ARC. Necesito algo que se serialice y deserialice usando objetos.
Muchas gracias.
Ahora puedes resolver este problema fácilmente usando JSONModel . JSONModel es una biblioteca que, en general, serializa / deserializa su objeto en función de la Clase. Incluso puede utilizar objetos no basados en nsobject para propiedades como int
, short
y float
. También puede atender JSON de complejos anidados.
Deserializar ejemplo . Al referirse a su ejemplo, en el archivo de cabecera:
#import "JSONModel.h"
@interface Person : JSONModel
@property (nonatomic, strong) NSString* firstname;
@property (nonatomic, strong) NSString* surname;
@end
en el archivo de implementación:
#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):
}
Ejemplo de serialización . En el archivo de implementación:
#import "JSONModelLib.h"
#import "yourPersonClass.h"
Person *person = [[Person alloc] init];
person.firstname = @"Jenson";
person.surname = @"Uee";
NSLog(@"%@", [person toJSONString]);
Este es un problema difícil porque los únicos datos que puede poner en JSON son directamente objetos simples (como NSString, NSArray, NSNumber ...) pero no clases personalizadas o tipos escalares. ¿Por qué? Sin construir todo tipo de declaraciones condicionales para incluir todos esos tipos de datos en ese tipo de objetos, una solución sería algo como:
//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];
Esto es complicado, aunque por lo que dije antes. Si tiene algún tipo de escalar u objetos personalizados, todo se derrumbará. Si es realmente importante poner en marcha algo como esto, sugeriría invertir tiempo y ver los enlaces de Ricard que le permiten ver los tipos de propiedad que ayudarían con las declaraciones condicionales necesarias para encerrar los valores en objetos seguros para el uso del diccionario.
Lo que hago para mis objetos es que tengo un método llamado "toDict" que devuelve un nsdictionary. EN este método, puse todos los atributos que necesito / quiero en el diccionario, por ejemplo
[user setObject:self.first_name forKey:@"first_name"];
[user setObject:self.last_name forKey:@"last_name"];
[user setObject:self.email forKey:@"email"];
Prueba este uno BWJSONMatcher
Es realmente simple y conveniente.
...
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];
...
tal vez esto puede ayudar a JLObjectStrip .
es lo mismo que dijo jacob pero itera incluso en la propiedad de la clase. esto te dará un diccionario / matriz, luego solo usa sbjson / jsonkit o lo que prefieras para construir tu cadena json.