2012-01-30 2 views
1

코코아를 사용하여 POST 요청에 대한 연구에 많은 시간을 할애했습니다.코코아 HTTP POST 요청 [Mac OS X]

나는 좋게 보이는 코드를 발견했습니다. 나는 그것이 나의 필요에 맞는 것처럼 그것을 바 꾸었습니다. 그러나 코드가 작동하지 않아서 코코아를 처음 사용하기 때문에 버그를 찾을 수 없습니다.

여기 내 코드입니다.

- (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 메시지는 "웹 요청 시작됨"과 "연결 초기화 됨"입니다. 그래서 나는 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response이 호출되지 않는다고 생각한다.

아무도이 문제를 해결할 수 있습니까?

감사합니다. Julian

답변

6

거의 제대로 했어!

나는 게시물이 1 년 된 것을 볼 수 있지만 그것이 다른 사람들을 도울 수 있고 내 자신의 참조로 여기에 올릴 수 있기를 바랍니다.

connection:didReceiveResponse:에 대한 애플의 설명서를 말한다 : - 연결의 요청에 대한 URL 응답을 구성 할 수있는 충분한 데이터를 수신했을 때 전송

.

대부분의 Apple 설명서와 마찬가지로이 역시 혼란스럽고 오해의 소지가 있습니다. 일반적으로 "URL 응답을 구성 할 수있는 충분한 데이터"가있을 경우 우리는 완전한 응답을 얻었음을 의미합니다. 이는 우리가 응답 본문을 가지고 있음을 의미합니다. 보편적으로 응답의 일부로 간주됩니다.

그러나이 경우 NSHTTPURLResponse 개체에는 본문이 없습니다. 내 생각에, Apple이 의미하는 바는 실제 데이터 (본문)를 제외한 응답에 대한 모든 것을 알려주는 "충분한"데이터를 가진 응답 헤더를 받았을 때 connection:didReceiveResponse:이 호출되었을 때입니다.

사실 많은 경우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

웹 데이터 란 무엇입니까? – RollRoll

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 : 것 return nil. 이는 요청 URL을 nil로 설정한다는 의미입니다. –

+0

내 코드에 뭔가 다른 것이 있어야합니다. 'mydomain'을 사용하면 프로토콜을 선도하는 외부 IP 주소를 의미했습니다. 그래서 이것은 문제가 아닙니다. 그리고'didFailWithError'는 불려지지 않습니다! 나는 함수를 테스트하기 위해'NSLog ("error");를 넣었다. 하지만 로그에 아무 것도 출력되지 않았습니다. –