2011-11-27 46 views
10

Ho definito alcune classi personalizzate, ad esempio Teacher, Student ... Ora ricevo le informazioni sull'insegnante (stringa JSON) dal server remoto.Come convertire JSON in oggetto

Come posso convertire la stringa JSON nell'oggetto Teacher.

In Java, è facile implementare un metodo comune per tutte le classi (Teacher, Student ...) con reflect.

Ma in Objective-C su iOS, il modo migliore che riesco a trovare è l'utilizzo di Entity of Core Data, che ha il metodo setValue:forKey. Innanzitutto converto la stringa JSON in NSDictionary, l'impostazione della coppia chiave-valore nel disctionary su Entry.

C'è qualche modo migliore?

(sto dalla Cina, così forse il mio inglese è povero, sorry!)

+0

La sua domanda era comprensibile, non preoccuparti :) – tekknolagi

+1

Haha, grazie :) –

+0

Date un'occhiata a questo link [JSON di opposizione] [1] [1]: http: // StackOverflow. it/questions/5645703/how-to-convert-json-data-to-objects-in-iphone – mH16

risposta

5

Questi sono tutti ottimi framework per l'analisi JSON di dizionari o altri primitivi, ma se stai cercando di evitare di fare un sacco di lavoro ripetitivo, controlla http://restkit.org. In particolare, consulta https://github.com/RestKit/RestKit/blob/master/Docs/Object%20Mapping.md Questo è l'esempio sulla mappatura degli oggetti in cui definisci la mappatura per la tua classe Insegnante e il json viene automaticamente convertito in un oggetto Insegnante utilizzando KVC. Se si utilizzano le chiamate di rete di RestKit, il processo è tutto trasparente e semplice, ma ho già avuto le mie chiamate di rete in atto e quello che mi serviva era di convertire il mio testo di risposta JSON in un oggetto User (insegnante nel tuo caso) e finalmente ho capito Come. Se è quello di cui hai bisogno, pubblica un commento e condividerò come farlo con RestKit.

Nota: presumo che JSON venga emesso utilizzando la convenzione mappata {"teacher": { "id" : 45, "name" : "Teacher McTeacher"}}. Se non è così, ma invece preferisci questo {"id" : 45, "name" : "Teacher McTeacher"} allora non preoccuparti ... la mappatura dell'oggetto design doc nel link ti mostra come fare questo ... qualche passo in più, ma non troppo male.

Questa è la mia richiamata da 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); 
} 

Si può ovviamente refactoring questo per renderlo più pulito, ma che ora risolve tutti i miei problemi .. non più di analisi ... basta risposta -> magia -> Oggetto

+0

Grazie mille. È proprio quello che sto cercando. Andare per favore –

+0

E ho già usato ASIHttp. –

+0

Ok ho aggiornato la mia risposta ... questo dovrebbe farti andare. Assicurati di seguire le istruzioni per ottenere RestKit nel tuo progetto esattamente come li vedi nella pagina github di RestKit. Ci sono voluti circa 30 minuti per inserirmi nel mio progetto b/c di tutti i passaggi richiesti, ma ora tutte le mie chiamate API sono state scritte rapidamente –

6

In primo luogo, si usa JSON parser? (in caso contrario, raccomanderei l'uso di SBJson).

In secondo luogo, perché non creare un metodo init di initWithDictionary nella classe personalizzata che restituisce l'oggetto stesso?

+0

Sì, utilizzo SBJson per analizzare la stringa json su NSDictionary. E penso che sia un modo efficace per creare un metodo initWithDictionary.Ma devo creare il metodo da tutte le classi. –

+3

Se si utilizza iOS 5, utilizzare la build nella classe NSJSONSerialization, se non si utilizza JSONKit, è più veloce di SBJSON. – Abizern