2011-02-11 12 views
6

Sto provando a mappare dinamicamente le informazioni JSON in oggetti diversi. Ma non riesco a capire come tenere sotto controllo l'intera situazione del puntatore, in quanto ciò che speravo funzionasse non lo fosse.Objective-C DRY JSON Mapping e creazione di oggetti

Finora il mio metodo è stato quello di creare un dizionario per ogni oggetto, mappando i puntatori variabili alle chiavi JSON equivalenti. Nel mio mappatore JSON, ho un metodo, parseJSONFromDictionary:withObject che deve scorrere il dizionario restituito dal valore JSONValue di SBJSON e assegnare i valori appropriati alle variabili appropriate nell'oggetto specificato.

-(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 è il dizionario che ha le variabili e le chiavi JSON, e il dict è ciò che viene restituito dal parser JSON.

Il grosso problema è che non riesco a fare start.[self.mappings objectForKey:key]. Non ne so molto di C, e chiaramente non ne so abbastanza dei puntatori, quindi come farei a creare questo tipo di sistema? So che non è il modo giusto per farlo, ma qual è la strada giusta? So che può essere fatto, come lo fa RestKit, ma non supportano OAuth, quindi purtroppo non posso usare il loro delizioso framework.

Il motivo per cui sto percorrendo questa rotta è perché l'API con cui sto lavorando è attualmente nella sua fase alpha. Voglio essere in grado di adattarmi facilmente a eventuali cambiamenti futuri senza dover riscrivere molte righe di codice. Voglio anche iniziare a programmare DRY-ly. So che l'analisi di JSON è molto ripetitiva e mi piacerebbe trovare un modo per ridurre la quantità di spese generali.

Grazie per qualsiasi aiuto!


EDIT: Sembra che ci sia una certa confusione su quello che sto chiedendo. I non hanno bisogno di aiuto per analizzare JSON. Sto già usando SBJSON. I non hanno bisogno di aiuto per effettuare richieste, sto già usando JDG's OAuthConsumer framework. I possono solo utilizzare framework che supportano OAuth 2.0.

ho bisogno di aiuto capire come prevenire questo:

-(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; 
}

Quindi, per favore fatemi sapere se avete qualche suggerimento su come combinare questi tipi di metodi in 1 metodo ...

+0

Hai consultato https://github.com/RestKit/RestKit? – Brenden

+0

Avevo guardato il Restkit. Non mi è piaciuto quello che ha fatto, e ancora non lo faccio. Mai nella mia vita ho visto una curva di allocazione della memoria più perfetta di quella di RestKit che gonfia gli oggetti in un loop. – MishieMoo

risposta

2

In realtà ho visto qualcuno fare questo utilizzando Objective Resources. Sebbene sia un buon modo per accedere agli oggetti, alcune delle implementazioni possono diventare disordinate. E devi usare tutto ciò che il server ti invia, che ti piaccia o no. Ho intenzione di stare lontano da questo adesso.

0

Guarda anche HTTPRiot che si occupa della maggior parte degli sforzi di comunicazione dalla tua spalla, gestisce le connessioni in modo asincrono, ecc. Questo Tutorial about JSON communications con iOS (Ruby piegato, ma minimo) mostra come usarlo; parte del codice è obsoleto, ma nel complesso arriva il messaggio.

+0

Ho già lavorato un sacco di JSON, quindi so come analizzare JSON in oggetti. Sto solo cercando di capire come non avere funzioni individuali per ogni oggetto che sto cercando di ottenere. Inoltre, ho bisogno di usare OAuth, quindi non posso usare HTTPRiot, o qualsiasi altro framework A MENO CHE abbiano già integrato OAuth (nota: non ne ho ancora trovato uno) – MishieMoo

+0

Poi applico l'altro consiglio e guardo in SBJSON (aka JSON Framework). Gestisce perfettamente il marshalling degli oggetti JSON mentre ti consente di gestire l'impianto idraulico OAuth sottostante. – yuvalz

+0

Sto già usando SBJSON. Questo ha a che fare con la creazione dell'oggetto DOPO che il JSON viene analizzato, non l'analisi JSON stessa. – MishieMoo

5

È possibile utilizzare KVC. Creare un setter per ogni valore nel dizionario JSON che si desidera inserire nell'oggetto e utilizzare -setValue:forKey: per impostare effettivamente i valori, ad es.

-(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

Potrebbe essere esattamente quello che sto cercando! Lo proverò sicuramente una volta tornerò al mio mac a casa. – MishieMoo

+0

Invece di scrivere il metodo extra setter (sto provando a scrivere il meno possibile il codice ripetitivo), un metodo come questo è adatto all'utilizzo di setValue: forKey http://www.otakunozoku.com/objective-c-class -proprietà/ ?? – MishieMoo

+0

quindi questo è sicuramente sulla falsariga che sto cercando. La mia implementazione è in esecuzione in issus con la creazione di altri oggetti all'interno della funzione, principalmente in relazione agli oggetti creati in una matrice. Alcune chiamate JSON restituiscono array di dizionari che devono quindi essere mappati in oggetti diversi ... Ovunque dove indirizzarmi? – MishieMoo

6

So che questo è un thread vecchio, ma ho pensato di inserirlo qui, il codice qui in https://github.com/mystcolor/JTObjectMapping potrebbe essere di aiuto nella mappatura degli oggetti. Dovrai avere i mapping e il tuo oggetto personalizzato pronto prima di usarlo. Ho trovato questo su googling .... non ha usato però. Hai bisogno di provarlo.