iOS:如何执行HTTP POST请求?

时间:2011-04-04 10:36:39

标签: iphone objective-c ios

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

据我所知,我应该管理通过NSURLConnection对象处理请求的连接,这会强制我拥有一个委托对象,而该对象又会处理数据事件。

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

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

7 个答案:

答案 0 :(得分: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

  3. 不要忘记设置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];
    }
    

答案 1 :(得分:13)

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

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

在各种情况下,HTTPS并发症并非易事,如果您想要在处理所有变体时保持健壮,那么您将发现ASI库是一个真正的帮助。

答案 2 :(得分:7)

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

答案 3 :(得分: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]);
}

或者更好的是,使用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];
}

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

答案 4 :(得分:1)

注意:Pure Swift 3(Xcode 8)示例: 请尝试以下示例代码。这是dataTask的{​​{1}}函数的简单示例。

URLSession

答案 5 :(得分:0)

Xcode 8和Swift 3.0

使用网址:

 let url = URL(string:"Download URL")!
 let req = NSMutableURLRequest(url:url)
 let config = URLSessionConfiguration.default
 let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)

 let task : URLSessionDownloadTask = session.downloadTask(with: req as URLRequest)
task.resume()

URLSession委托电话:

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {

}


func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, 
didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) {
                   print("downloaded \(100*writ/exp)" as AnyObject)

}

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){

}

使用Block GET / POST / PUT / DELETE:

 let request = NSMutableURLRequest(url: URL(string: "Your API URL here" ,param: param))!,
        cachePolicy: .useProtocolCachePolicy,
        timeoutInterval:"Your request timeout time in Seconds")
    request.httpMethod = "GET"
    request.allHTTPHeaderFields = headers as? [String : String] 

    let session = URLSession.shared

    let dataTask = session.dataTask(with: request as URLRequest) {data,response,error in
        let httpResponse = response as? HTTPURLResponse

        if (error != nil) {
         print(error)
         } else {
         print(httpResponse)
         }

        DispatchQueue.main.async {
           //Update your UI here
        }

    }
    dataTask.resume()

为我工作正常..试试100%结果保证

答案 6 :(得分:0)

以下是使用NSURLSession对iOS 8+进行POST HTTP请求的方式:

- (void)call_PostNetworkingAPI:(NSURL *)url withCompletionBlock:(void(^)(id object,NSError *error,NSURLResponse *response))completion
{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    config.URLCache = nil;
    config.timeoutIntervalForRequest = 5.0f;
    config.timeoutIntervalForResource =10.0f;
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];
    NSMutableURLRequest *Req=[NSMutableURLRequest requestWithURL:url];
    [Req setHTTPMethod:@"POST"];

    NSURLSessionDataTask *task = [session dataTaskWithRequest:Req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {

            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
            if (dict != nil) {
                completion(dict,error,response);
            }
        }else
        {
            completion(nil,error,response);
        }
    }];
    [task resume];

}

希望这能满足您的以下要求。