在 iOS 上发送 HTTP POST 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15749486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:59:38  来源:igfitidea点击:

Sending an HTTP POST request on iOS

iosobjective-cautomatic-ref-countinghttp-postnsurlconnection

提问by Daan Luttik

I'm trying to send an HTTP Post with the iOS application that I'm developing but the push never reaches the server although I do get a code 200 as response (from the urlconnection). I never get a response from the server nor does the server detect my posts (the server does detect posts coming from android)

我正在尝试使用我正在开发的 iOS 应用程序发送 HTTP Post,但推送从未到达服务器,尽管我确实收到了代码 200 作为响应(来自 urlconnection)。我从来没有得到服务器的响应,服务器也没有检测到我的帖子(服务器确实检测到来自 android 的帖子)

I do use ARC but have set pd and urlConnection as strong.

我确实使用 ARC,但已将 pd 和 urlConnection 设置为强。

This is my code for sending the request

这是我发送请求的代码

 NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
                                    initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@",dk.baseURL,@"daantest"]]];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"text/xml"
   forHTTPHeaderField:@"Content-type"];

    NSString *sendString = @"<data><item>Item 1</item><item>Item 2</item></data>";

    [request setValue:[NSString stringWithFormat:@"%d", [sendString length]] forHTTPHeaderField:@"Content-length"];

    [request setHTTPBody:[sendString dataUsingEncoding:NSUTF8StringEncoding]];
    PushDelegate *pushd = [[PushDelegate alloc] init];
    pd = pushd;
    urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:pd];
    [urlConnection start];

this is my code for the delegate

这是我的委托代码

#import "PushDelegate.h"

@implementation PushDelegate
@synthesize data;

-(id) init
{
    if(self = [super init])
    {
        data = [[NSMutableData alloc]init];
        [data setLength:0];
    }
    return self;
}


- (void)connection:(NSURLConnection *)connection didWriteData:(long long)bytesWritten totalBytesWritten:(long long)totalBytesWritten
{
    NSLog(@"didwriteData push");
}
- (void)connectionDidResumeDownloading:(NSURLConnection *)connection totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes
{
    NSLog(@"connectionDidResumeDownloading push");
}

- (void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL
{
    NSLog(@"didfinish push @push %@",data);
}

- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
    NSLog(@"did send body");
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [self.data setLength:0];
    NSHTTPURLResponse *resp= (NSHTTPURLResponse *) response;
    NSLog(@"got response with status @push %d",[resp statusCode]);
}

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

    NSLog(@"recieved data @push %@", data);
}

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

    NSLog(@"didfinishLoading%@",responseText);

}

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

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

    NSURLCredential *credential = [NSURLCredential credentialWithUser:username
                                                             password:password
                                                          persistence:NSURLCredentialPersistenceForSession];
    [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}

@end

The console always prints the following lines and the following lines only:

控制台总是打印以下几行并且仅打印以下几行:

2013-04-01 20:35:04.341 ApprenticeXM[3423:907] did send body
2013-04-01 20:35:04.481 ApprenticeXM[3423:907] got response with status @push 200
2013-04-01 20:35:04.484 ApprenticeXM[3423:907] didfinish push @push <>

回答by iPatel

The following code describes a simple example using POSTmethod.(How one can pass data by POSTmethod)

下面的代码描述了一个使用POST方法的简单示例。(如何通过POST方法传递数据

Here, I describe how one can use of POST method.

在这里,我描述了如何使用 POST 方法。

1.Set post string with actual username and password.

1.使用实际用户名和密码设置帖子字符串。

NSString *post = [NSString stringWithFormat:@"Username=%@&Password=%@",@"username",@"password"]; 

2.Encode the post string using NSASCIIStringEncodingand also the post string you need to send in NSData format.

2.使用 post 字符串NSASCIIStringEncoding以及您需要以 NSData 格式发送的 post 字符串进行编码。

NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 

You need to send the actual length of your data. Calculate the length of the post string.

您需要发送数据的实际长度。计算post字符串的长度。

NSString *postLength = [NSString stringWithFormat:@"%d",[postData length]]; 

3.Create a Urlrequest with all the properties like HTTPmethod, http header field with length of the post string. Create URLRequestobject and initialize it.

3.创建一个带有所有属性的 Urlrequest,如HTTP方法、带有 post 字符串长度的 http 标头字段。创建URLRequest对象并初始化它。

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 

Set the Url for which your going to send the data to that request.

设置您要向该请求发送数据的 URL。

[request setURL:[NSURL URLWithString:@"http://www.abcde.com/xyz/login.aspx"]]; 

Now, set HTTPmethod (POST or GET). Write this lines as it is in your code.

现在,设置HTTP方法(POST 或 GET)。按照代码中的原样编写此行。

[request setHTTPMethod:@"POST"]; 

Set HTTPheader field with length of the post data.

HTTP使用 post 数据的长度设置头字段。

[request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 

Also set the Encoded value for HTTP header Field.

还要设置 HTTP 标头字段的编码值。

[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

Set the HTTPBodyof the urlrequest with postData.

HTTPBody使用 postData设置urlrequest 的 。

[request setHTTPBody:postData];

4.Now, create URLConnection object. Initialize it with the URLRequest.

4.现在,创建 URLConnection 对象。使用 URLRequest 对其进行初始化。

NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

It returns the initialized url connection and begins to load the data for the url request. You can check that whether you URLconnection is done properly or not using just if/elsestatement as below.

它返回初始化的 url 连接并开始加载 url 请求的数据。您可以URL使用如下所示的if/else语句检查连接是否正确完成。

if(conn) {
    NSLog(@"Connection Successful");
} else {
    NSLog(@"Connection could not be made");
}

5.To receive the data from the HTTP request , you can use the delegate methods provided by the URLConnection Class Reference. Delegate methods are as below.

5、从HTTP请求中接收数据,可以使用URLConnection Class Reference提供的delegate方法。委托方法如下。

// This method is used to receive the data which we get using post method.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data

// This method receives the error report in case of connection is not made to server. 
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 

// This method is used to process the data after connection has made successfully.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection

Also ReferThisandThisdocumentationfor POSTmethod.

另请参阅文档以了解POST方法。

And here is best example with source code of HTTPPost Method.

这是HTTPPost 方法源代码的最佳示例

回答by Mannam Brahmam

-(void)sendingAnHTTPPOSTRequestOniOSWithUserEmailId: (NSString *)emailId withPassword: (NSString *)password{
//Init the NSURLSession with a configuration
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];

//Create an URLRequest
NSURL *url = [NSURL URLWithString:@"http://www.example.com/apis/login_api"];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];

//Create POST Params and add it to HTTPBody
NSString *params = [NSString stringWithFormat:@"email=%@&password=%@",emailId,password];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];

//Create task
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    //Handle your response here
    NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
     NSLog(@"%@",responseDict);
}];
   [dataTask resume];
}

回答by nickygerritsen

I am not really sure why, but as soon as I comment out the following method it works:

我不太确定为什么,但是一旦我注释掉以下方法,它就会起作用:

connectionDidFinishDownloading:destinationURL:

Furthermore, I don't think you need the methods from the NSUrlConnectionDownloadDelegate protocol, only those from NSURLConnectionDataDelegate, unless you want some download information.

此外,我认为您不需要 NSUrlConnectionDownloadDelegate 协议中的方法,只需要 NSURLConnectionDataDelegate 中的方法,除非您需要一些下载信息。

回答by Esqarrouth

Heres the method I used in my logging library: https://github.com/goktugyil/QorumLogs

这是我在日志库中使用的方法:https: //github.com/goktugyil/QorumLogs

This method fills html forms inside Google Forms. Hope it helps someone using Swift.

此方法在 Google 表单中填充 html 表单。希望它可以帮助使用 Swift 的人。

var url = NSURL(string: urlstring)

var request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = postData.dataUsingEncoding(NSUTF8StringEncoding)
var connection = NSURLConnection(request: request, delegate: nil, startImmediately: true)

回答by Dilip Tiwari

Objective C

目标 C

Post API with parameters and validate with url to navigate if json
response key with status:"success"

发布带有参数的 API 并使用 url 进行验证以导航
状态是否为“成功”的json响应键

NSString *string= [NSString stringWithFormat:@"url?uname=%@&pass=%@&uname_submit=Login",self.txtUsername.text,self.txtPassword.text];
    NSLog(@"%@",string);
    NSURL *url = [NSURL URLWithString:string];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    NSURLResponse *response;
    NSError *err;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
    NSLog(@"responseData: %@", responseData);
    NSString *str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    NSLog(@"responseData: %@", str);
        NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
                                                         options:kNilOptions
                                                           error:nil];
    NSDictionary* latestLoans = [json objectForKey:@"status"];
    NSString *str2=[NSString stringWithFormat:@"%@", latestLoans];
    NSString *str3=@"success";
    if ([str3 isEqualToString:str2 ])
    {
        [self performSegueWithIdentifier:@"move" sender:nil];
        NSLog(@"successfully.");
    }
    else
    {
        UIAlertController *alert= [UIAlertController
                                 alertControllerWithTitle:@"Try Again"
                                 message:@"Username or Password is Incorrect."
                                 preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                   handler:^(UIAlertAction * action){
                                                       [self.view endEditing:YES];
                                                   }
                             ];
        [alert addAction:ok];
        [[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor redColor]];
        [self presentViewController:alert animated:YES completion:nil];
        [self.view endEditing:YES];
      }

JSON Response: {"status":"success","user_id":"58","user_name":"dilip","result":"You have been logged in successfully"} Working code

JSON 响应:{"status":"success","user_id":"58","user_name":"dilip","re​​sult":"您已成功登录"} 工作代码

**

**

回答by Ronny Morán

Sending an HTTP POST request on iOS (Objective c):

在 iOS 上发送 HTTP POST 请求(目标 c):

-(NSString *)postexample{

// SEND POST
NSString *url = [NSString stringWithFormat:@"URL"];
NSString *post = [NSString stringWithFormat:@"param=value"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d",[postData length]];


NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:@"POST"];
[request setURL:[NSURL URLWithString:url]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];

NSError *error = nil;
NSHTTPURLResponse *responseCode = nil;

//RESPONDE DATA 
NSData *oResponseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];

if([responseCode statusCode] != 200){
    NSLog(@"Error getting %@, HTTP status code %li", url, (long)[responseCode statusCode]);
    return nil;
}

//SEE RESPONSE DATA
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Response" message:[[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];

return [[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
}

回答by Tech

Using Swift 3 or 4 you can access these http request for sever communication.

使用 Swift 3 或 4,您可以访问这些 http 请求以进行服务器通信。

// For POST data to request

// 用于POST数据请求

 func postAction()  {
//declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid
let parameters = ["id": 13, "name": "Hyman"] as [String : Any]
//create the url with URL
let url = URL(string: "www.requestURL.php")! //change the url
//create the session object
let session = URLSession.shared
//now create the URLRequest object using the url object
var request = URLRequest(url: url)
request.httpMethod = "POST" //set http method as POST
do {
    request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass dictionary to nsdata object and set it as request body
} catch let error {
    print(error.localizedDescription)
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
    guard error == nil else {
        return
    }
    guard let data = data else {
        return
    }
    do {
        //create json object from data
        if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
            print(json)
            // handle json...
        }
    } catch let error {
        print(error.localizedDescription)
    }
})
task.resume() }

// For get the data from request

// 从请求中获取数据

func GetRequest()  {
    let urlString = URL(string: "http://www.requestURL.php") //change the url

    if let url = urlString {
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if error != nil {
                print(error ?? "")
            } else {
                if let responceData = data {
                    print(responceData) //JSONSerialization
                    do {
                        //create json object from data
                        if let json = try JSONSerialization.jsonObject(with:responceData, options: .mutableContainers) as? [String: Any] {
                            print(json)
                            // handle json...
                        }
                    } catch let error {
                        print(error.localizedDescription)
                    }
                }
            }
        }
        task.resume()
    }
}

// For get the download content like image or video from request

// 用于从请求中获取图像或视频等下载内容

func downloadTask()  {
    // Create destination URL
    let documentsUrl:URL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
    let destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile.jpg")
    //Create URL to the source file you want to download
    let fileURL = URL(string: "http://placehold.it/120x120&text=image1")
    let sessionConfig = URLSessionConfiguration.default
    let session = URLSession(configuration: sessionConfig)
    let request = URLRequest(url:fileURL!)

    let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
        if let tempLocalUrl = tempLocalUrl, error == nil {
            // Success
            if let statusCode = (response as? HTTPURLResponse)?.statusCode {
                print("Successfully downloaded. Status code: \(statusCode)")
            }

            do {
                try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
            } catch (let writeError) {
                print("Error creating a file \(destinationFileUrl) : \(writeError)")
            }

        } else {
            print("Error took place while downloading a file. Error description: %@", error?.localizedDescription ?? "");
        }
    }
    task.resume()

}