2011-11-27 20 views
10

He definido algunas clases personalizadas, como Teacher, Student ... Ahora recibo información del profesor (cadena JSON) del servidor remoto.Cómo convertir JSON en el objeto

¿Cómo puedo convertir la cadena JSON en Teacher objeto.

En Java, es fácil implementar un método común para todas las clases (Teacher, Student ...) con reflect.

Pero en Objective-C en iOS, la mejor forma que puedo encontrar es usar Entity of Core Data, que tiene el método setValue:forKey. Primero convierto la cadena JSON a NSDictionary, establezca el par clave-valor en el disctionary al Entry.

¿Hay formas mejores?

(estoy de China, por lo que tal vez mi Inglés es pobre, lo siento!)

+0

Su pregunta era comprensible, no se preocupe :) – tekknolagi

+1

jaja, Gracias :) –

+0

Tener un vistazo a este enlace [JSON para el objeto] [1] [1]: http: // stackoverflow. com/questions/5645703/how-to-convert-json-data-to-objects-in-iphone – mH16

Respuesta

5

Todos estos son buenos marcos para el análisis JSON de diccionarios u otras primitivas, pero si está buscando evitar hacer un montón de trabajos repetitivos, consulte http://restkit.org. Específicamente, mira https://github.com/RestKit/RestKit/blob/master/Docs/Object%20Mapping.md Este es el ejemplo en el mapeo de objetos donde defines el mapeo para tu clase de maestro y el json se convierte automágicamente en un objeto de maestro usando KVC. Si utiliza las llamadas de red de RestKit, el proceso es transparente y simple, pero ya tenía instaladas mis llamadas de red y lo que necesitaba era convertir mi texto de respuesta json a un objeto User (Profesor en su caso) y finalmente me di cuenta cómo. Si eso es lo que necesita, publique un comentario y le contaré cómo hacerlo con RestKit.

Nota: Asumiré que el json se emite utilizando la convención mapeada {"teacher": { "id" : 45, "name" : "Teacher McTeacher"}}. Si no es así, sino como este {"id" : 45, "name" : "Teacher McTeacher"}, no se preocupe ... el documento de diseño de asignación de objetos en el enlace muestra cómo hacer esto ... unos pocos pasos adicionales, pero no tan mal.

Esta es mi devolución de llamada desde ASIHTTPRequest

- (void)requestFinished:(ASIHTTPRequest *)request { 
    id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:[request.responseHeaders valueForKey:@"Content-Type"]]; // i'm assuming your response Content-Type is application/json 
    NSError *error; 
    NSDictionary *parsedData = [parser objectFromString:apiResponse error:&error]; 
    if (parsedData == nil) { 
     NSLog(@"ERROR parsing api response with RestKit...%@", error); 
     return; 
    } 

    [RKObjectMapping addDefaultDateFormatterForString:@"yyyy-MM-dd'T'HH:mm:ssZ" inTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; // This is handy in case you return dates with different formats that aren't understood by the date parser 

    RKObjectMappingProvider *provider = [RKObjectMappingProvider new]; 

    // This is the error mapping provider that RestKit understands natively (I copied this verbatim from the RestKit internals ... so just go with it 
    // This also shows how to map without blocks 
    RKObjectMapping* errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]]; 
    [errorMapping mapKeyPath:@"" toAttribute:@"errorMessage"]; 
    [provider setMapping:errorMapping forKeyPath:@"error"]; 
    [provider setMapping:errorMapping forKeyPath:@"errors"]; 

    // This shows you how to map with blocks 
    RKObjectMapping *teacherMapping = [RKObjectMapping mappingForClass:[Teacher class] block:^(RKObjectMapping *mapping) { 
     [mapping mapKeyPath:@"id" toAttribute:@"objectId"]; 
     [mapping mapKeyPath:@"name" toAttribute:@"name"]; 
    }]; 

    [provider setMapping:teacherMapping forKeyPath:@"teacher"]; 

    RKObjectMapper *mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:provider]; 
    Teacher *teacher = nil; 
    RKObjectMappingResult *mappingResult = [mapper performMapping]; 
    teacher = [mappingResult asObject]; 

    NSLog(@"Teacher is %@ with id %lld and name %@", teacher, teacher.objectId, teacher.name); 
} 

Puede obviamente refactorizar esto para hacerle más limpia, pero que ahora resuelve todos mis problemas .. no más de análisis ... sólo la respuesta -> magia -> Objeto

+0

Muchas gracias. Es justo lo que estoy buscando. Continúa por favor –

+0

Y ya he usado ASIHttp. –

+0

Ok, actualicé mi respuesta ... esto debería ayudarte. Solo asegúrate de seguir las instrucciones para colocar RestKit en tu proyecto exactamente como los ves en la página RestKit github. Me tomó alrededor de 30 minutos para incluirlo en mi proyecto b/c de todos los pasos necesarios, pero ahora todas mis llamadas API se escriben rápidamente –

6

primer lugar, no se utiliza JSON Analizador? (De lo contrario, recomendaría usar SBJson).

En segundo lugar, ¿por qué no crear un método de inicio initWithDictionary en su clase personalizada que devuelve autoobjeto?

+0

Sí, uso SBJson para analizar json string en NSDictionary. Y creo que es una forma efectiva de crear un método initWithDictionary.Pero tengo que crear el método de todas las clases. –

+3

Si usa iOS 5, use la compilación en la clase NSJSONSerialization, si no utiliza JSONKit, es más rápido que SBJSON. – Abizern