iOS:如何执行HTTP POST请求?

Fed*_*can 128 iphone objective-c ios

我正在接近iOS开发,我想让我的第一个应用程序之一执行HTTP POST请求.

据我所知,我应该管理通过NSURLConnection对象处理请求的连接,这迫使我有一个委托对象,而后者又处理数据事件.

有人可以通过一个实际例子澄清这个任务吗?

我应该联系https端点发送身份验证数据(用户名和密码)并获取纯文本响应.

Anh*_* Do 168

您可以按如下方式使用NSURLConnection:

  1. 设置NSURLRequest:requestWithURL:(NSURL *)theURL用于初始化请求.

    如果你需要指定一个POST请求和/或HTTP头,使用NSMutableURLRequest

    • (void)setHTTPMethod:(NSString *)method
    • (void)setHTTPBody:(NSData *)data
    • (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
  2. 使用NSURLConnection以下两种方式发送您的请求:

    • 同步: (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error

      这将返回NSData您可以处理的变量.

      重要提示:请记住在单独的线程中启动同步请求以避免阻止UI.

    • 异步: (void)start

不要忘记设置NSURLConnection的委托来处理连接,如下所示:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [self.data setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
    [self.data appendData:d];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    [[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", @"")
                                 message:[error localizedDescription]
                                delegate:nil
                       cancelButtonTitle:NSLocalizedString(@"OK", @"") 
                       otherButtonTitles:nil] autorelease] show];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSString *responseText = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];

    // Do anything you want with it 

    [responseText release];
}

// Handle basic authentication challenge if needed
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    NSString *username = @"username";
    NSString *password = @"password";

    NSURLCredential *credential = [NSURLCredential credentialWithUser:username
                                                             password:password
                                                          persistence:NSURLCredentialPersistenceForSession];
    [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
Run Code Online (Sandbox Code Playgroud)

  • Apple表示使用同步请求是"不推荐"的http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html尽管如果你知道足以搞乱不同的线程,你可能会没事的. (4认同)
  • 通常,您会将凭证存储在钥匙串中并在那里检索它们以处理Basic-Auth. (2认同)
  • iOS 5以上也可以使用+(void)sendAsynchronousRequest:(NSURLRequest*)请求队列:(NSOperationQueue*)队列completionHandler:(void(^)(NSURLResponse*,NSData*,NSError*))处理程序 (2认同)

Rog*_*ger 13

编辑:ASIHTTPRequest已被开发人员抛弃.它仍然是非常好的IMO,但你现在应该看看其他地方.

如果您正在处理HTTPS,我强烈建议您使用ASIHTTPRequest库.即使没有https,它也为这样的东西提供了一个非常好的包装器,虽然通过简单的http做自己并不难,但我认为这个库很好并且是一个很好的入门方式.

HTTPS的复杂性在各种情况下都是微不足道的,如果您想要在处理所有变体时都很健壮,那么您将发现ASI库是一个真正的帮助.

  • ASIHTTPRequest库已被其开发者正式放弃,因为这篇文章指出:http://allseeing-i.com/[request_release]; ,我建议你使用其他库,因为开发人员建议,甚至更好,尝试学习NSURLRequest :)干杯. (13认同)
  • [AFNetworking](http://afnetworking.com/)是大多数人现在使用的. (3认同)

Jes*_*her 7

我想我会稍微更新一下这篇文章并说很多iOS社区在被放弃之后已经转移到了AFNetworkingASIHTTPRequest.我强烈推荐它.它是一个很好的包装器NSURLConnection,允许异步调用,基本上你可能需要的任何东西.

  • 我知道接受的答案是好的,不是故意的举止或任何事情,但这肯定会有更多的赞成.也许如果添加一个示例和一些代码片段,问题表明? (2认同)

Kyl*_*son 6

这是iOS7 +的更新答案.它使用NSURLSession,新的热点.免责声明,这是未经测试的,并写在文本字段中:

- (void)post {
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com/dontposthere"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    // Uncomment the following two lines if you're using JSON like I imagine many people are (the person who is asking specified plain text)
    // [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    // [request addValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
    [request setHTTPMethod:@"POST"];
    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }];
    [postDataTask resume];
}

-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(    NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
    completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}
Run Code Online (Sandbox Code Playgroud)

或者更好的是,使用AFNetworking 2.0+.通常我会将AFHTTPSessionManager子类化,但我将这一切都放在一个方法中以得到一个简洁的例子.

- (void)post {
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"https://example.com"]];
    // Many people will probably want [AFJSONRequestSerializer serializer];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    // Many people will probably want [AFJSONResponseSerializer serializer];
    manager.responseSerializer = [AFHTTPRequestSerializer serializer];
    manager.securityPolicy.allowInvalidCertificates = NO; // Some servers require this to be YES, but default is NO.
    [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"username" password:@"password"];
    [[manager POST:@"dontposthere" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
        NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        NSLog(@"darn it");
    }] resume];
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是JSON响应序列化程序,则responseObject将是JSON响应中的对象(通常是NSDictionary或NSArray).