2012-01-30 68 views
1

我花了很多時間研究使用Cocoa的POST請求。Cocoa HTTP POST請求[Mac OS X]

我發現一些看起來不錯的代碼。我改變了它,因爲它符合我的需求。但是代碼沒有工作,我找不到這個bug,因爲我對可可非常陌生。

這是我的代碼。

- (IBAction)sendForm:(id)sender 
{ 
    NSLog(@"web request started"); 
    NSString *post = [NSString stringWithFormat:@"firstName=%@&lastName=%@&eMail=%@&message=%@", firstName.stringValue, lastName.stringValue, eMail.stringValue, message.stringValue]; 
    NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 
    NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]]; 

    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; 
    [request setURL:[NSURL URLWithString:@"myDomain/form.php"]]; 
    [request setHTTPMethod:@"POST"]; 
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
    [request setHTTPBody:postData]; 

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
    if(theConnection) 
    { 
     webData = [[NSMutableData data] retain]; 
     NSLog(@"connection initiated"); 
    } 
} 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
    [webData appendData:data]; 
    NSLog(@"connection received data"); 
} 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    NSLog(@"connection received response"); 
    NSHTTPURLResponse *ne = (NSHTTPURLResponse *)response; 
    if([ne statusCode] == 200) 
    { 
     NSLog(@"connection state is 200 - all okay"); 
     NSString *html = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding]; 
     [[webView mainFrame] loadHTMLString:html baseURL:[NSURL URLWithString:@"myDomain"]]; 
    } 
} 

但是我收到的唯一兩條NSLog消息是「web請求啓動」和「連接啓動」。 所以我認爲- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response沒有被調用。

任何人可以幫助我這個問題?

感謝您的幫助,朱利安

回答

6

你幾乎做得對!

我可以看到這篇文章已有一年了,但希望它可以幫助其他人,併爲我自己的參考,我在這裏張貼這個。

蘋果的connection:didReceiveResponse:文件說: -

當連接已經收到了足夠的數據來構建其請求的URL 發送響應。

與大多數蘋果文檔一樣,這也是令人困惑和誤導。通常,當我們有足夠的數據來構建URL響應時,意味着我們有完整的響應,這進一步意味着我們也有響應主體;這被普遍認爲是答覆的一部分。

但是在這種情況下,NSHTTPURLResponse對象沒有主體。所以我的猜測是,蘋果公司的意思是 - connection:didReceiveResponse:在我們收到響應頭時有調用,該頭有「足夠」的數據讓我們知道除了實際數據(主體)以外的所有響應。

實際上很多時候你會注意到connection:didReceiveData:connection:didReceiveResponse:被調用後被稱爲

因此,我們可以如下修改代碼: -

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 

    NSLog(@"web request started"); 
    NSString *post = [NSString stringWithFormat:@"firstName=%@&lastName=%@&eMail=%@&message=%@", firstName.stringValue, lastName.stringValue, eMail.stringValue, message.stringValue]; 
    NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding]; 
    NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]]; 

    NSLog(@"Post data: %@", post); 

    NSMutableURLRequest *request = [NSMutableURLRequest new]; 
    [request setURL:[NSURL URLWithString:@"https://example.com/form.php"]]; 
    [request setHTTPMethod:@"POST"]; 
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
    [request setHTTPBody:postData]; 

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

    if(theConnection) { 
     webData = [NSMutableData data]; 
     NSLog(@"connection initiated"); 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [webData appendData:data]; 
    NSLog(@"connection received data"); 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    NSLog(@"connection received response"); 
    NSHTTPURLResponse *ne = (NSHTTPURLResponse *)response; 
    if([ne statusCode] == 200) { 
     NSLog(@"connection state is 200 - all okay"); 
    } else { 
     NSLog(@"connection state is NOT 200"); 
    } 
} 

-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    NSLog(@"Conn Err: %@", [error localizedDescription]); 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    NSLog(@"Conn finished loading"); 
    NSString *html = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding]; 
    NSLog(@"OUTPUT:: %@", html); 
} 
+1

什麼是webdata? – RollRoll 2013-06-15 18:58:48

2

你有沒有試圖執行錯誤的委託方法?

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    // do something with error 
} 

它可能發生,你沒有互聯網連接,或別的東西是錯誤的之前NSURLConnection能夠建立連接。在這種情況下,您將不會收到http響應或任何其他數據。該錯誤將提供更多信息。

[編輯]

我只注意到在示例代碼的URL不包含主機名。如果這是您使用的確切代碼,請確保將請求發送到正確的URL。

// Replace 
[NSURL URLWithString:@"myDomain/form.php"] 
// with a correct url like 
[NSURL URLWithString:@"http://mydomain.com/form.php"]; 

錯誤委託方法實際上會爲您提供抱怨錯誤URL的錯誤。

+0

事實上,即使你提供一個有效的域名,但沒有協議(「HTTP://」),調用+ URLWithString:將返回零。這意味着你將請求的URL設置爲零。 – 2012-01-30 16:38:04

+0

我的代碼一定有其他錯誤。對於'mydomain',我的意思是帶有領先協議的外部IP地址。所以這不是問題。而'didFailWithError'甚至不會被調用!我把一個'NSLog(「error」);'來測試這個函數。但是Log沒有輸出任何東西 – 2012-02-05 03:14:12