2011-04-23 17 views
7

En java-land, hay un puñado de bibliotecas útiles que convertirán cadenas json en objetos de tipo coincidente. Las bibliotecas json que he visto para Cocoa simplemente crean NSDictionaries y NSArrays anidados. ¿Hay alguna herramienta que vaya a dar el paso adicional de reconstituir el tipo de objeto que quiero?Cacao: deserializar json cadena a objetos personalizados (no NSDictionary, NSArray)

Así, por ejemplo, si tengo una clase llamada "unicornio", con una propiedad "maneColor", y tengo JSON que tiene este aspecto:

{ 
"maneColor":"silver" 
} 

que puede crear una instancia automáticamente un objeto de unicornio con "maneColor" establecido en "plata".

+0

+1 para unicornios – psy

Respuesta

7

No conozco ninguna implementación específica, pero la codificación de clave-valor te acerca mucho a lo que deseas: Key Value Coding Guide. He tenido buenos resultados combinando streamed json parsing con KVC.

El método -setValue: forKey: hace que la adaptación de datos serializados a objetos personalizados sea bastante sencilla. Para continuar con su ejemplo, crearía una clase Unicornio con todos los métodos de acceso requeridos: -setName:/- name, -setManeColor/-maneColor, etc. (Es posible que pueda usar propiedades para algunos valores esperados, pero existen casos, como con el valor maneColor, donde probablemente desee escribir un setter personalizado para convertir de la cadena de nombre de color a un objeto NSColor o UIColor).

También deseará agregar dos métodos más a su objeto personalizado : -setValue: forUndefinedKey: y -valueForUndefinedKey :. Estos son los métodos que serán llamados si su objeto no tiene métodos de acceso que coincidan con una clave pasada a los métodos de KVC. Puede capturar valores inesperados o no admitidos aquí, y almacenarlos o ignorarlos según sea necesario.

Cuando envía -setValue: forKey: al objeto Unicornio, el marco busca accesadores que coincidan con el patrón de teclas. Por ejemplo, si la clave es "maneColor" y está estableciendo el valor, el marco verifica si su objeto implementa -setManeColor :. Si es así, invoca ese método, pasando el valor; de lo contrario, se llama a -setValue: forUndefinedKey: y si su objeto no lo implementa, se lanza una excepción.

Cuando el delegado de su analizador recibe la notificación de que ha comenzado el análisis de un objeto unicornio json, crea una instancia de un objeto Unicornio. A medida que su analizador devuelve los datos analizados a usted, use -setValue: forKey: añadir los datos a su objeto:

- (void)parserDidBeginParsingDictionary: (SomeParser *)p 
{ 
    self.currentUnicorn = [ Unicorn unicorn ]; 
} 

- (void)parser: (SomeParser *)p didParseString: (NSString *)string 
      forKey: (NSString *)key 
{ 
    [ self.currentUnicorn setValue: string forKey: key ] 
} 

- (void)parserDidFinishParsingDictionary: (SomeParser *)p 
{ 
    [ self.unicorns addObject: self.currentUnicorn ]; 
} 
+0

Gracias más tensión! Esto es ciertamente cerca de lo que estoy buscando. – morgancodes

7

Uso Jastor - https://github.com/elado/jastor ya tiene Analizada JSON en NSDictionary y rellena una instancia de bienes Objetivo- Clase C

NSDictionary *parsedJSON = (yajl, JSONKit etc) 
Unicorn *unicorn = [[Unicorn alloc] initWithDictionary:parsedJSON]; 

unicorn.maneColor // "silver" 
+0

Una alternativa es KVCObjectMapping. https://github.com/tuyennguyencanada/KVCObjectMapping – occulus

0

Apple ha añadido la clase NSJSONSerialization a iOS 5.0, que, de acuerdo con el documentation, realiza lo siguiente:

utiliza la clase NSJSONSerialization para convertir JSON para Fundación objetos y convertir Fundación objetos a JSON .

Un objeto que puede ser convertido en JSON debe tener las siguientes propiedades :

El objeto de nivel superior es un NSArray o NSDictionary. Todos los objetos son instancias de NSString, NSNumber, NSArray, NSDictionary o NSNull. Todas las claves del diccionario son instancias de NSString.Los números no son NaN o infinito.

Aquí hay tutorial y wrapper method para comenzar.

+1

Tenga en cuenta que 'NSJSONSerialization' solo funciona con objetos Foundation. Creo que la clase Unicorn no es una clase de Fundación :) – ULazdins

1

Como cualquier subclase de NSObject se ajusta a NSKeyValueCoding protocolo:

NSDictionary *parsedJSON = //whatever 
id <NSKeyValueCoding> entity = [[CustomNSObjectSubclass alloc] init]; 
[entity setValuesForKeysWithDictionary:parsedJSON]; 
Cuestiones relacionadas