Gửi yêu cầu HTTP POST trên iOS


86

Tôi đang cố gắng gửi một Bài đăng HTTP bằng ứng dụng iOS mà tôi đang phát triển nhưng lệnh đẩy không bao giờ đến được máy chủ mặc dù tôi nhận được mã 200 dưới dạng phản hồi (từ kết nối url). Tôi không bao giờ nhận được phản hồi từ máy chủ cũng như máy chủ không phát hiện ra các bài đăng của tôi (máy chủ không phát hiện các bài đăng đến từ android)

Tôi sử dụng ARC nhưng đã đặt pd và urlConnection là mạnh.

Đây là mã của tôi để gửi yêu cầu

 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];

đây là mã của tôi cho người được ủy quyền

#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

Bảng điều khiển luôn in các dòng sau và chỉ các dòng sau:

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 <>

Câu trả lời:


188

Đoạn mã sau mô tả một ví dụ đơn giản bằng cách sử dụng POSTphương thức. ( Cách người ta có thể truyền dữ liệu bằng POSTphương thức )

Ở đây, tôi mô tả cách người ta có thể sử dụng phương thức POST.

1. Đặt chuỗi bài đăng với tên người dùng và mật khẩu thực tế.

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

2. Mã hóa chuỗi bài đăng bằng cách sử dụng NSASCIIStringEncodingvà cả chuỗi bài đăng bạn cần gửi ở định dạng NSData.

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

Bạn cần gửi độ dài thực tế của dữ liệu của mình. Tính độ dài của chuỗi bài.

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

3. Tạo một Urlrequest với tất cả các thuộc tính như HTTPphương thức, trường tiêu đề http với độ dài của chuỗi bài đăng. Tạo URLRequestđối tượng và khởi tạo nó.

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

Đặt Url mà bạn sẽ gửi dữ liệu đến yêu cầu đó.

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

Bây giờ, hãy đặt phương thức HTTP ( POST hoặc GET ). Viết những dòng này như trong mã của bạn.

[request setHTTPMethod:@"POST"]; 

Đặt HTTPtrường tiêu đề với độ dài của dữ liệu bài đăng.

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

Đồng thời đặt giá trị Mã hóa cho Trường tiêu đề HTTP.

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

Đặt HTTPBodyurlrequest với postData.

[request setHTTPBody:postData];

4. Bây giờ, tạo đối tượng URLConnection. Khởi tạo nó bằng URLRequest.

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

Nó trả về kết nối url đã khởi tạo và bắt đầu tải dữ liệu cho yêu cầu url. Bạn có thể kiểm tra xem URLkết nối của bạn có được thực hiện đúng cách hay không bằng cách sử dụng câu lệnh if / else như bên dưới.

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

5. Để nhận dữ liệu từ yêu cầu HTTP, bạn có thể sử dụng các phương thức ủy quyền do Tham chiếu lớp URLConnection cung cấp. Các phương pháp ủy quyền như bên dưới.

// 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

Cũng tham khảo Tài liệu này Tài liệu này để biết POSTphương pháp.

Và đây là ví dụ tốt nhất với mã nguồn của Phương pháp HTTPPost.


1
Cũng kiểm tra xem không có bộ nhớ đệm nào đang diễn ra. Điều đó sẽ giải thích tại sao bạn nhận được '200' mà không có bất kỳ điều gì xảy ra trên máy chủ.
Jelle

Kiểm tra câu trả lời được chấp nhận của stackoverflow.com/questions/405151/… và / hoặc google để biết "chính sách bộ nhớ cache nsurlconnection"
Jelle

1
Mặc dù câu trả lời đã được chấp nhận rất nhiều lần, mã cho sẵn trong câu trả lời này có một số vấn đề khó hiểu và sẽ gây rắc rối trong thực tế.
CouchDeveloper

1
@iPatel Nhưng chúng tôi có thể gửi dữ liệu hình ảnh bằng mã phương thức đăng đã cho ở trên không.
iHulk

1
Thật không may, mã này không chính xác và dễ bị tấn công. Nếu người dùng tình cờ có ký tự "&" trong mật khẩu, tất cả các ký tự khác sẽ được phân tích cú pháp như một tham số POST bổ sung. Có thể cố ý thao túng.
ge0rg

4
-(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];
}

2

Tôi thực sự không chắc tại sao, nhưng ngay sau khi tôi nhận xét phương pháp sau, nó hoạt động:

connectionDidFinishDownloading:destinationURL:

Hơn nữa, tôi không nghĩ bạn cần các phương thức từ giao thức NSUrlConnectionDownloadDelegate, chỉ những phương thức từ NSURLConnectionDataDelegate, trừ khi bạn muốn một số thông tin tải xuống.


Tôi muốn thông tin tải đó là lý do tại sao tôi có chức năng connectionDidFinishDownloading: destinationUrl:
Daan Luttik

1
Rõ ràng NSURLConnectionDownloadDelegate chỉ hoạt động trong các ứng dụng Newsstand .... Ít nhất đó là những gì chủ đề này nói: stackoverflow.com/questions/6735121/...
nickygerritsen

2

Đây là phương pháp tôi đã sử dụng trong thư viện ghi nhật ký của mình: https://github.com/goktugyil/QorumLogs

Phương pháp này điền vào các biểu mẫu html bên trong Google Biểu mẫu. Hy vọng nó sẽ giúp ai đó sử dụng 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)

1

Gửi yêu cầu HTTP POST trên iOS (Mục tiêu 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];
}

Đây là mới ... Bắt trả lời 4 năm sau khi câu hỏi của bạn được đăng: p
Daan Luttik

"Postexample" Chức năng này nhanh hơn là đáp ứng : p @DaanLuttik
Ronny Morán

1

Sử dụng Swift 3 hoặc 4, bạn có thể truy cập yêu cầu http này để liên lạc với máy chủ.

// Đối với dữ liệu POST để yêu cầu

 func postAction()  {
//declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid
let parameters = ["id": 13, "name": "jack"] 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() }

// Để lấy dữ liệu từ yêu cầu

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()
    }
}

// Để lấy nội dung tải xuống như hình ảnh hoặc video theo yêu cầu

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()

}

1

Mục tiêu C

Đăng API với các tham số và xác thực bằng url để điều hướng nếu
khóa phản hồi json có trạng thái: "thành công"

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];
      }

Phản hồi JSON : {"status": "success", "user_id": "58", "user_name": "dilip", "result": "Bạn đã đăng nhập thành công"} Mã làm việc

**

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.