2012-11-14 16 views
6

Così ho appena passato a RestKit 0.2 e attualmente sto usando il nuovo "HttpClient" che è fondamentalmente un AFHTTPClient. Ho questa riga di codice:JSON Risposta in postPath AFHTTPClient

RKObjectManager* objectManager = [RKObjectManager sharedManager]; 
NSDictionary* params = [[NSDictionary alloc] initWithObjectsAndKeys: login, @"username", password, @"password", nil]; 

[[objectManager HTTPClient]postPath:@"users/login/?format=json" parameters:params 
    success:^(AFHTTPRequestOperation *operation, id responseObject) 
    { 
     //reponseObject vs operation.response 
     NSLog(@"%@", responseObject); 
    } 
    failure:^(AFHTTPRequestOperation *operation, NSError *error) 
    { 
     NSLog(@"ERROR"); 
    }]; 

chiamate questo post restituire una risposta JSON nella forma: { "api_key": ".... "" username ":" ...."}. Così semplice.

Prima di passare a 0,2, sono stato in grado di ottenere la chiave api_key nella risposta facendo:

[[RKClient sharedClient] post:@"https://stackoverflow.com/users/login/?format=json" usingBlock:^(RKRequest *request) 
{ 
    request.onDidLoadResponse = ^(RKResponse *response) 
    { 
     id parsedResponse = [response parsedBody:NULL]; 
     NSString *apiKey = [parsedResponse valueForKey:@"api_key"]; 
    } 
    }.....]; 

http://restkit.org/api/master/Classes/RKResponse.html

Ma ora, non posso farlo e se faccio un NSLog sulla responseObject, ottengo:

< 7b227265 61736f6e 223a2022 41.504.920 4b657920 666f756e 64222c20 22.617.069 5f6b6579 223a2022 61356661 65323437 66336264 35316164 39396338 63393734 36386438 34636162 36306537 65386331 222c2022 73.756.363 657.373 22 3a207472 75657d>

E la cosa strana è che se lo faccio:

 NSLog(@"%@", operation.responseString); 

ho la JSON (in NSString) rivelando.

Quindi due domande:

1) Perché la stampa della responseObject mostrandomi codice esadecimale, e non la risposta in realtà JSON?

2) Perché se eseguo operation.responseString mostra l'oggetto risposta effettivo? C'è un modo per ottenere i dati reali in ResponseObject dopo essere stati analizzati dal JSON?

Grazie!

risposta

11

Quello che stai vedendo, se non sbaglio, sono i byte grezzi provenienti da NSData che ti vengono dati quando viene chiamato il tuo blocco di successo.

L'esagono che hai postato si legge:

{"reason": "API Key found", "api_key": "a5fae247f3bd51ad99c8c97468d84cab60e7e8c1", "success": true}

La ragione per la seconda NSLog vi mostra ciò che si vuole è che la stringa di formato %@ chiama la descrizione (correggetemi se sbaglio qui, SO) dell'oggetto lo si passa e lo NSData probabilmente sa che è una stringa sottostante.

Quindi, su come ottenere il JSON. È davvero piuttosto semplice. Una volta che avete l'oggetto risposta, si può fare qualcosa di simile:

NSDictionary* jsonFromData = (NSDictionary*)[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];

Che cosa questo farà per voi è l'uso restituire un NSDictionary che codifica l'oggetto principale nel JSON e poi ogni valore nel dizionario sarà essere del tipo NSString, NSNumber, NSArray, NSDictionary o NSNull. Vedere NSJSONSserialization per la documentazione.

Il NSJSONReadingMutableContainers rende i dizionari e gli array mutabili. È solo un residuo del mio codice.

Speriamo che tu sia su iOS 5 o successivo, o dovrai trovare un'altra soluzione per l'analisi.

+2

Anche se questa è una risposta giusta, ma penso che @ phix23 sia meglio, almeno per la rete AFNetworking. ;) – Kjuly

17

AFNetworking deve creare un'istanza di AFJSONRequestOperation. Probabilmente crea invece un valore di base AFHTTPRequestOperation (controllare [operation class]) risultante in un oggetto NSData come risposta.

Assicurati di registrare la classe operazione nel metodo init della vostra AFHTTPClient sottoclasse (initWithBaseURL):

[self registerHTTPOperationClass:[AFJSONRequestOperation class]]; 

// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 
[self setDefaultHeader:@"Accept" value:@"application/json"]; 

Si potrebbe anche provare a utilizzare AFJSONRequestOperation direttamente in questo modo:

NSURLRequest *request = [[objectManager HTTPClient] requestWithMethod:@"POST" path:@"users/login/?format=json" parameters:params]; 
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
    NSLog(@"JSON: %@", JSON); 
} failure:nil]; 
[[objectManager HTTPClient] enqueueHTTPRequestOperation:operation]; 
+2

+1 per l'uso corretto di AFNetworking. Dovrebbe accettare questo. – Kjuly

+1

questo ha aiutato, grazie mille –

3
success:^(AFHTTPRequestOperation *operation, id responseObject) { 
    NSData *responseData = operation.HTTPRequestOperation.responseData; 
    id parsedResponse = [RKMIMETypeSerialization objectFromData:responseData MIMEType:RKMIMETypeJSON error:nil]; 
    NSString *apiKey = [parsedResponse valueForKey:@"api_key"] 
}