2012-03-29 15 views
8

Breve riassunto, il nostro sviluppatore precedente ha utilizzato ASIHTTPRequest per effettuare richieste POST e recuperare i dati dal nostro servizio web. Per ragioni sconosciute questa parte della nostra app ha smesso di funzionare. Sembrava un buon momento per le prove future e andare con AFNetworking. Il servizio web REST viene eseguito nel framework CakePHP.AFNetworking POST to REST webservice

In breve, non ricevo la stringa di risposta richiesta utilizzando AFNetworking.

So che il webservice funziona perché sono in grado di inviare correttamente i dati e ricevere la risposta corretta con ricciolo: ricciolo -d "di dati [modello] [Field0] = field0value dati & [Modello] [field1] = field1value" https://example.com/api/class/function.plist

Per le precedenti istruzioni per lo sviluppatore, ho trovato il seguente.

#import "AFHTTPRequestOperation.h"  

… 

- (IBAction)loginButtonPressed { 

    NSURL *url = [NSURL URLWithString:@"https://example.com/api/class/function.plist"]; 

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 

    [request setHTTPMethod:@"POST"]; 

    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 

    [request setValue:[usernameTextField text] forHTTPHeaderField:@"data[User][email]"]; 

    [request setValue:[passwordTextField text] forHTTPHeaderField:@"data[User][password]"]; 

    AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease]; 

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 

     NSLog(@"operation hasAcceptableStatusCode: %d", [operation.response statusCode]); 

     NSLog(@"response string: %@ ", operation.responseString); 

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 

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

    }]; 

    [operation start]; 

} 

uscita: operazione hasAcceptableStatusCode: 200 stringa risposta: un file vuoto plist

tentata soluzione 1: AFNetworking Post Request la soluzione proposta utilizza una funzione di chiamata AFHTTPRequestOperation operationWithRequest. Tuttavia, quando cerco di utilizzare la soluzione, viene visualizzato un avviso "Metodo di classe" + operazioneWithRequest: completamento: "non trovato (il valore di default restituisce" id ""

Soluzione tentata 2: NSURLConnection. Output: I'm able per stampare il registro successo messaged ma non la stringa di risposta * aggiornamento -.. ritorna plist vuoto

NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; 
NSString *httpBodyData = @"data[User][email][email protected]&data[User][password]=awesomepassword"; 
[httpBodyData dataUsingEncoding:NSUTF8StringEncoding]; 
[req setHTTPMethod:@"POST"]; 
[req setHTTPBody:[NSData dataWithContentsOfFile:httpBodyData]]; 
NSHTTPURLResponse __autoreleasing *response; 
NSError __autoreleasing *error; 
[NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error]; 

// *update - returns blank plist 
NSData *responseData = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil]; 
NSString *str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
NSLog(@"responseData %@",str); 

if (error == nil && response.statusCode == 200) { 
    // Process response 
    NSLog(@"success");//returns success code of 200 but blank 
    NSLog(@"resp %@", response); 
} else { 
    // Process error 
    NSLog(@"error"); 
} 
+0

Ciao, Pouria, hai provato a utilizzare NSURLConnection per inviare una richiesta sincrona? – 8vius

+0

tentato soluzione 2: è come ho provato NSURLConnection. – Airuop

+0

Avete tutto sul lato server impostato correttamente? Come l'analisi delle estensioni, i layout per la risposta e le visualizzazioni per loro? Sembra più un problema del server che uno client. – 8vius

risposta

18

Queste sono le linee essenziali (che eliminano le condizioni che ho realizzato per mio uso personale) che hanno finito per soddisfare la mia richiesta al servizio web. Grazie per i suggerimenti @ 8vius e @mattt!

- (IBAction)loginButtonPressed {   
    NSURL *baseURL = [NSURL URLWithString:@"https://www.example.com/api/class"]; 

    //build normal NSMutableURLRequest objects 
    //make sure to setHTTPMethod to "POST". 
    //from https://github.com/AFNetworking/AFNetworking 
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:baseURL]; 
    [httpClient defaultValueForHeader:@"Accept"]; 

    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: 
          [usernameTextField text], kUsernameField, 
          [passwordTextField text], kPasswordField, 
          nil]; 

    NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" 
      path:@"https://www.example.com/api/class/function" parameters:params]; 

    //Add your request object to an AFHTTPRequestOperation 
    AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] 
             initWithRequest:request] autorelease]; 

    //"Why don't I get JSON/XML/Property List in my HTTP client callbacks?" 
    //see: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ 
    //mattt's suggestion http://stackoverflow.com/a/9931815/1004227 - 
    //-still didn't prevent me from receiving plist data 
    //[httpClient registerHTTPOperationClass: 
    //   [AFPropertyListParameterEncoding class]]; 

    [httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]]; 

    [operation setCompletionBlockWithSuccess: 
     ^(AFHTTPRequestOperation *operation, 
     id responseObject) { 
     NSString *response = [operation responseString]; 
     NSLog(@"response: [%@]",response); 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     NSLog(@"error: %@", [operation error]); 
    }]; 

    //call start on your request operation 
    [operation start]; 
    [httpClient release]; 
} 
+0

La registrazione per le operazioni di plist interessa solo le operazioni di richiesta create usando 'AFHTTPClient -HTTPRequestOperationWithRequest: success: failure:'. 'alloc init'-ing 'AFHTTPRequestOperation' ti darà sempre un' AFHTTPRequestOperation'. – mattt

+0

grazie, @mattt! – Airuop

+0

@pouria, cos'è Path qui. È come lo stesso URL. Per favore aiutami sono rimasto bloccato su Path. –

6

Usa AFHTTPClient -postPath:parameters:success:failure:, passando i parametri (annidati dizionari/array vanno bene) Se vi aspettate un plist indietro. , assicurati di avere il registro del cliente AFPropertyListRequestOperation.

In ogni caso, setValue:forHTTPHeaderField: non è quello che vuoi qui. HTTP headers servono per specificare informazioni sulla richiesta stessa; i dati fanno parte del corpo della richiesta. AFHTTPClient converte automaticamente i parametri in una stringa di query per le richieste GET o un corpo HTTP per POST, et al.

+0

Ho risolto questo problema ma ho la sensazione che sto ancora facendo qualcosa di sbagliato o inefficiente. Lo apprezzerei molto se avessi una rapida occhiata alla mia soluzione. Grazie! – Airuop