2012-12-19 10 views
5

Sto cercando di far funzionare un messaggio POST. Ho visto un paio di post che descrivono come fare, come ad esempio this one, ma non riesco ancora a farlo funzionare. Qui di seguito è il mio codice Objective-C:Impossibile utilizzare il post http iOS con NSURLConnection

NSString * urlString = @"http://magicthegatheringdatabase.com/test.php"; 
NSURL *aUrl = [NSURL URLWithString: urlString]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl 
                 cachePolicy:NSURLRequestUseProtocolCachePolicy 
                timeoutInterval:60.0]; 

NSString *postString = [NSString stringWithFormat:@"tes1=%@&test2=%@", 
         [@"hello" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 
         [@"world" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 
NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding]; 
[request setHTTPBody: postBody]; 

[request addValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 

NSString *postLength = [NSString stringWithFormat:@"%d", postBody.length]; 
[request addValue: postLength forHTTPHeaderField:@"Content-Length"]; 

[request setHTTPMethod:@"POST"]; 

NSError * error = nil; 
NSData *returnData = [NSURLConnection sendSynchronousRequest: request 
              returningResponse: nil 
                 error: &error]; 
NSLog(@"%p, %@", error, error.localizedDescription); 

NSString * returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding]; 
NSLog(@"Result: %@", returnString); 

Ed ecco il mio PHP:

<?php 
    print_r($_REQUEST); 
    print_r($_POST); 
    print_r($_GET); 

    echo file_get_contents('php://input'); 
?> 

Se faccio funzionare il codice, ottengo il seguente ingresso:

 
2012-12-19 09:24:09.061 MTG Deck Builder[7921:570f] 0x0, (null) 
2012-12-19 09:24:09.062 MTG Deck Builder[7921:570f] Result: Array 
(
) 
Array 
(
) 
Array 
(
) 

Se a navigare direttamente all'URL e aggiungere ?test1=hello&test2=world (utilizzando GET ovviamente anziché POST) ottengo:

 
Array 
(
    [test1] => hello 
    [test2] => world 
    [phpbb3_5e63r_u] => 1 
    [phpbb3_5e63r_k] => 
    [phpbb3_5e63r_sid] => 7ff37e188aa8e0ab57fae6a52f0d1f7b 
    [__utma] => 86369156.392372889.1349352986.1352901458.1353328580.11 
    [__utmz] => 86369156.1351935106.8.2.utmcsr=hankinsoft.com|utmccn=(referral)|utmcmd=referral|utmcct=/website/forum/10-mtg-magic-the-gathering-trading-card-game-tcg-da/634-new-forum.html 
    [style_cookie] => null 
) 
Array 
(
) 
Array 
(
    [test1] => hello 
    [test2] => world 
) 

Quindi so che il mio PHP sta registrando correttamente le richieste/ricevute, ma non sono sicuro del perché il mio POST tramite il codice obiettivo-c non funzioni. Sono abbastanza sicuro di trascurare qualcosa di stupido. Qualche suggerimento su cosa mi manca?

+2

Provare impostando il tipo di contenuto e la dimensione. –

+0

Fai un'altra cosa invece di impostare nil in errore, passa qualche istanza di NSError, così puoi sapere che cosa sta arrivando l'errore. Spero, risolverà il problema. –

+0

Btw, vuoi sapere di [RestKit] (https://github.com/RestKit/RestKit). – moonwave99

risposta

3

Questo perché NSURLConnection non gestisce correttamente i reindirizzamenti.

Quando si invia la richiesta POST all'URL http://magicthegatheringdatabase.com/test.php, il server rispondono con 301 Moved Permanently e reindirizza a http://www.magicthegatheringdatabase.com/test.php.

Invece di inviare la stessa richiesta al nuovo URL, NSURLConnection crea una nuova richiesta GET e scarta la richiesta originale HTTPBody. Questo comportamento è dovuto allo HTTP specifications che proibisce il reindirizzamento automatico di richieste diverse da HEAD e GET senza una conferma da parte dell'utente. La modifica del metodo su GET è errata, ma almeno è un metodo sicuro, che non può danneggiare la risorsa HTTP.

Questo problema può essere risolto con due opzioni:

  1. si può semplicemente modificare l'URL della richiesta di essere http://www.magicthegatheringdatabase.com/test.php.

  2. Oppure si può creare un'istanza di NSURLConnection con un delegato e attuare il connection:willSendRequest:redirectResponse: al fine di gestire il reindirizzamento correttamente come descritto nella risposta alla this question. Funzionerà anche se il reindirizzamento cambia ma richiede di scrivere altro codice in quanto è necessario attendere la risposta, creare un oggetto NSMutableData, aggiungere i byte man mano che vengono e gestire tutto in modo asincrono (vedere Apple Developer Documentation). Tuttavia, eseguire le attività in modo asincrono è sempre una buona idea: puoi cancellarle se necessario e non rischierai di bloccare il tuo thread per molto tempo (quando sei nel thread principale, qualcosa di più lungo di 1 secondo è un tempo lungo)).

+0

Grazie per la risposta e i dettagli. Sapevo che dovevo trascurare qualcosa di semplice e questo è stato. – Kyle

1

Cambio:

NSString *postString = [NSString stringWithFormat:@"tes1=%@&test2=%@", 
          [@"hello" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 
          [@"world" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 

Ora aggiungere

[request setHTTPMethod:@"POST"]; 
2

si dovrebbe cercare di aggiungere il seguente:

[request addValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"];