2011-02-11 16 views
6

Estoy tratando de mapear dinámicamente la información JSON en diferentes objetos. Pero no puedo descifrar cómo controlar toda la situación del puntero, ya que lo que esperaba que no funcionara.Objective-C DRY JSON Mapeo y creación de objetos

Hasta ahora, mi metodología ha sido crear un diccionario para cada objeto, mapeando los punteros variables a las teclas JSON equivalentes. En mi mapeador JSON, tengo un método, parseJSONFromDictionary:withObject que se supone que itera sobre el diccionario devuelto por SBJSON's JSONValue y asigne los valores apropiados a las variables apropiadas en el objeto dado.

-(NSObject *)parseJSONFromDictionary:(NSDictionary *)dict withObject:(NSObject *)start{ 
    for (NSString *key in dict) { 
     if ([[self.mappings objectForKey:key] isMemberOfClass:[NSString class]]) { 
      start.[self.mappings objectForKey:key] = [[dict valueForKey:key] stringValue]; 
     } 
    } 
    return start; 
}

mappings es el diccionario que tiene las variables claves y JSON, y el dict es lo que se devuelve desde el analizador JSON.

El gran problema es que no puedo hacer start.[self.mappings objectForKey:key]. No sé mucho sobre C, y claramente no sé lo suficiente sobre los punteros, entonces, ¿cómo podría crear este tipo de sistema? Sé que esa no es la manera correcta de hacer esto, pero ¿cuál es el camino correcto? Sé que se puede hacer, como lo hace RestKit, pero no son compatibles con OAuth, por lo que lamentablemente no puedo usar su adorable framework.

La razón por la que voy por esta ruta es porque la API con la que estoy trabajando se encuentra actualmente en su etapa alfa. Quiero ser capaz de adaptarme fácilmente a cualquier cambio futuro sin tener que volver a escribir muchas líneas de código. También quiero comenzar a programar DRY-ly. Sé que el análisis JSON es muy repetitivo, y me gustaría encontrar una manera de reducir la cantidad de sobrecarga.

¡Gracias por toda la ayuda!


EDIT: Parece que hay cierta confusión en cuanto a lo que estoy pidiendo. I no necesita necesita ayuda para analizar JSON. Estoy usando SBJSON ya. I no necesito ayuda para hacer solicitudes, ya estoy usando JDG's OAuthConsumer framework. I solo puede usar frameworks compatibles con OAuth 2.0.

sí necesito ayuda encontrar la manera de evitar esto:

-(Class1 *)parseJsonForClass1:(NSString *)inputString { 
    NSDictionary *outputDict = [inputString JSONValue]; 
    Class1 *instance1 = [self mapObjectsForClass1From:outputDict]; 
    return instance1; 
} 

-(Class2 *)parseJsonForClass2:(NSString *)inputString { 
    NSDictionary *outputDict = [inputString JSONValue]; 
    Class2 *instance2 = [self mapObjectsForClass2From:outputDict]; 
    return instance2; 
} 

-(Class3 *)parseJsonForClass3:(NSString *)inputString { 
    NSDictionary *outputDict = [inputString JSONValue]; 
    Class2 *instance3 = [self mapObjectsForClass3From:outputDict]; 
    return instance3; 
} 

-(Class1 *)mapObjectsForClass1From:(NSDictionary *)dict { 
    Class1 *object1 = [[Class1 alloc] init]; 
    object1.name = [[dict valueForKey:@"name"] stringValue]; 
    object1.date = [[dict valueForKey:@"date"] stringValue]; 
    object1.objId = [[dict valueForKey:@"id"] intValue]; 

    return object1; 
} 

-(Class2 *)mapObjectsForClass2From:(NSDictionary *)dict { 
    Class2 *object2 = [[Class2 alloc] init]; 
    object2.something = [[dict valueForKey:@"something"] stringValue]; 
    object2.title = [[dict valueForKey:@"title"] stringValue]; 
    object2.imageUrl = [[dict valueForKey:@"image_url"] stringValue]; 

    return object2; 
} 

-(Class3 *)mapObjectsForClass3From:(NSDictionary *)dict { 
    Class3 *object3 = [[Class3 alloc] init]; 
    object3.foo = [[dict valueForKey:@"bar"] stringValue]; 
    object3.flag = [[dict valueForKey:@"is_member"] boolValue]; 
    object3.obj1 = [[Class1 alloc] init]; 
    object3.obj1 = [self mapOjectsForClass1From:[dict objectForKey:@"name1"]]; 

    return object3; 
}

Así que por favor, hágamelo saber si usted tiene alguna sugerencia sobre cómo combinar este tipo de métodos en 1 método ...

+0

¿Ha consultado https://github.com/RestKit/RestKit? – Brenden

+0

Había mirado Restkit. No me gustó lo que hizo, y todavía no lo hago. Nunca en mi vida he visto una curva de asignación de memoria más perfecta que RestKit inflando objetos en un bucle. – MishieMoo

Respuesta

2

De hecho, recientemente vi a alguien hacer esto usando Objective Resources. Si bien es una buena forma de acceder a los objetos, parte de la implementación puede complicarse. Y debe usar todo lo que el servidor le envíe, le guste o no. Me voy a mantener alejado de esto en este momento.

0

También vea HTTPRiot que se encarga de la mayor parte del esfuerzo de comunicación de su hombro, maneja las conexiones de forma asíncrona, etc. Este Tutorial about JSON communications con iOS (Ruby doblada, pero mínima) muestra cómo usarlo; parte del código está desactualizado, pero en general pasa el mensaje.

+0

He hecho un montón de trabajo JSON antes, así que sé cómo analizar JSON en objetos. Solo intento descubrir cómo no tener funciones individuales para cada objeto que intento obtener. Además, necesito usar OAuth para no poder usar HTTPRiot o cualquier otro framework A MENOS QUE ya tengan incorporado OAuth (nota: aún no encontré ninguno) – MishieMoo

+0

Luego busco la otra recomendación y miro en SBJSON (también conocido como JSON Framework). Gestiona sin problemas el cálculo de referencias de objetos JSON a la vez que le permite administrar las tuberías subyacentes de OAuth. – yuvalz

+0

Ya estoy usando SBJSON. Esto tiene que ver con la creación de objetos DESPUÉS de que el JSON sea analizado, no el análisis JSON. – MishieMoo

5

Puede usar KVC. Cree un colocador para cada valor en el diccionario JSON que desee insertar en su objeto y use -setValue:forKey: para establecer realmente los valores, p.

-(NSObject *)parseJSONFromDictionary:(NSDictionary *)dict withObject:(NSObject *)start 
{ 
    for (NSString *key in [dict allKeys]) 
    { 
     NSString* propertyName = [[self mappings] objectForKey: key]; 
     [start setValue: [dict objectForKey: key] forKey: propertyName]; 
     // the above line will throw an exception if start does not have a set accessor for property 
    } 
    return start; 
} 
+0

¡Eso puede ser exactamente lo que estoy buscando! Definitivamente probaré esto una vez que regrese a mi mac en casa. – MishieMoo

+0

En lugar de escribir el método extra setter (estoy tratando de escribir el menor código repetitivo posible), un método como este sería adecuado para usar setValue: forKey http://www.otakunozoku.com/objective-c-class -propiedades/?? – MishieMoo

+0

así que definitivamente es lo que estoy buscando. Mi implementación se ejecuta en issus con la creación de otros objetos dentro de la función, principalmente en relación con los objetos creados en una matriz. Algunas de las llamadas JSON devuelven matrices de diccionarios que luego deben asignarse a objetos diferentes ... ¿A cualquier lugar al que apuntarme? – MishieMoo

6

Sé que esto es un hilo viejo pero pensé en poner esto aquí, el código aquí en https://github.com/mystcolor/JTObjectMapping sería de ayuda en el mapeo de objetos. Deberá tener las asignaciones y su objeto personalizado listo antes de usar esto. Encontré esto en google ... pero no lo he usado. Necesito probarlo