2012-01-30 60 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