HTTP POST-запрос какао [Mac OS X] - PullRequest
1 голос
/ 30 января 2012

Я потратил много времени на исследование запросов POST с использованием какао.

Я нашел код, который выглядел хорошо. Я изменил его так, как он соответствует моим потребностям. Но код не работал, и я не могу найти ошибку, потому что я довольно новичок в какао.

Вот мой код.

- (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 не называются.

Кто-нибудь может мне помочь с этим вопросом?

Спасибо за помощь, Джулиан

Ответы [ 2 ]

7 голосов
/ 02 февраля 2013

Вы почти все сделали правильно!

Я вижу, что посту год, но в надежде, что он может помочь другим, и для моей собственной справки, я публикую это здесь.

Документация Apple для connection:didReceiveResponse: гласит: -

Отправляется, когда соединение получило достаточно данных для построения URL-ответа на свой запрос.

Как и в большинстве документов Appleэто тоже сбивает с толку и может вводить в заблуждение.Обычно, когда у нас «достаточно данных для построения ответа URL», это означает, что у нас есть полный ответ, что также означает, что у нас также есть тело ответа;который универсально считается частью ответа.

Однако в этом случае объект NSHTTPURLResponse не имеет тела.Поэтому я предполагаю, что Apple имеет в виду, что 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);
}
2 голосов
/ 30 января 2012

Вы пытались реализовать метод делегирования ошибок?

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

Может случиться, что у вас нет подключения к интернету, или что-то еще не так, прежде чем NSURLConnection сможет установить соединение,В этом случае вы не получите ответ http или любые другие данные.Ошибка предоставит дополнительную информацию.

[edit]

Я только что заметил, что URL в примере кода не содержит имени хоста.Если это именно тот код, который вы используете, убедитесь, что вы отправили запрос на правильный URL-адрес.

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

Метод делегирования ошибок на самом деле выдаст вам ошибку с жалобой на неправильный URL-адрес.

...