iOS에서 HTTP POST 요청 보내기


86

개발중인 iOS 애플리케이션을 사용하여 HTTP Post를 보내려고하는데 URL 연결에서 응답으로 코드 200을 받았지만 푸시가 서버에 도달하지 않습니다. 서버로부터 응답을받지 못하거나 서버가 내 게시물을 감지하지 못합니다 (서버가 Android에서 오는 게시물을 감지 함).

ARC를 사용하지만 pd 및 urlConnection을 강력하게 설정했습니다.

이것은 요청을 보내는 코드입니다.

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

이것은 대리인을위한 내 코드입니다.

#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

콘솔은 항상 다음 행과 다음 행만 인쇄합니다.

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

답변:


188

다음 코드는 POST메서드 를 사용하는 간단한 예제를 설명합니다 . ( 메서드로 데이터를 전달하는 POST방법 )

여기서는 POST 방식을 사용하는 방법을 설명합니다.

1. 실제 사용자 이름과 비밀번호로 게시 문자열을 설정합니다.

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

2.NSASCIIStringEncoding NSData 형식으로 보내야하는 게시 문자열과 함께 게시 문자열을 인코딩 합니다.

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

데이터의 실제 길이를 보내야합니다. 포스트 문자열의 길이를 계산합니다.

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

3.HTTP post 문자열의 길이가있는 메소드, http 헤더 필드와 같은 모든 속성으로 Urlrequest를 생성 합니다. 만들기 URLRequest개체를하고 초기화합니다.

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

해당 요청에 데이터를 보낼 URL을 설정하십시오.

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

이제 HTTP 메소드 ( POST 또는 GET )를 설정하십시오. 이 줄을 코드에있는 그대로 작성하십시오.

[request setHTTPMethod:@"POST"]; 

HTTP게시물 데이터의 길이로 헤더 필드를 설정 합니다.

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

HTTP 헤더 필드에 대한 인코딩 된 값도 설정하십시오.

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

HTTPBodypostData로 urlrequest를 설정합니다 .

[request setHTTPBody:postData];

4. 이제 URLConnection 객체를 생성합니다. URLRequest로 초기화하십시오.

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

초기화 된 URL 연결을 반환하고 URL 요청에 대한 데이터를로드하기 시작합니다. 아래와 같이 if / elseURL만으로 연결이 제대로 되었는지 확인할 수 있습니다 .

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

5. HTTP 요청에서 데이터를 수신하려면 URLConnection 클래스 참조에서 제공하는 위임 메서드를 사용할 수 있습니다. 위임 방법은 다음과 같습니다.

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

또한 참조하십시오 문서 에 대한 POST방법을.

그리고 여기에 HTTPPost Method의 소스 코드를 사용한 가장 좋은 예가 있습니다.


1
또한 진행중인 캐싱이 없는지 확인하십시오. 그것은 서버에서 아무 일도 일어나지 않고 '200'을 얻은 이유를 설명합니다.
Jelle

의 허용 대답 확인 stackoverflow.com/questions/405151/...을 및 / 또는 "있는 NSURLConnection의 캐시 정책"에 대한 구글
Jelle

1
답변이 너무 많이 받아 들여졌음에도 불구 하고이 답변의 주어진 코드에는 많은 눈부신 문제가 있으며 실제로는 문제가 될 것입니다.
CouchDeveloper 2014 년

1
@iPatel하지만 위에 주어진 포스트 메소드 코드를 사용하여 이미지 데이터를 보낼 수 있습니다.
iHulk 2014-08-22

1
안타깝게도이 코드는 올바르지 않으며 주입 공격을 받기 쉽습니다. 사용자의 암호에 "&"문자가있는 경우 모든 추가 문자는 추가 POST 매개 변수로 구문 분석됩니다. 의도적 인 조작이 가능합니다.
ge0rg 2015

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

이유는 확실하지 않지만 다음 방법을 설명하자마자 작동합니다.

connectionDidFinishDownloading:destinationURL:

또한 다운로드 정보를 원하지 않는 한 NSUrlConnectionDownloadDelegate 프로토콜의 메서드가 필요하지 않고 NSURLConnectionDataDelegate의 메서드 만 필요하다고 생각합니다.


다운로드 정보를 원합니다. 그래서 connectionDidFinishDownloading : destinationURL :
Daan Luttik 2013-04-01

1
분명히 NSURLConnectionDownloadDelegate는 뉴스 가판대 응용 프로그램에서 작동합니다 .... 적어도 그이 스레드의 말씀입니다 : stackoverflow.com/questions/6735121/...
nickygerritsen

2

로깅 라이브러리에서 사용한 방법은 다음과 같습니다. https://github.com/goktugyil/QorumLogs

이 메소드는 Google Forms 내의 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)

1

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

이것은 새로운 것입니다 ... 귀하의 질문이 게시 된 후 4 년 후 답변 받기 : p
Daan Luttik 17

이 "postexample"기능은 더 빠른 즉 응답 P @DaanLuttik :
로니 모란

1

Swift 3 또는 4를 사용하면 서버 통신을 위해 이러한 http 요청에 액세스 할 수 있습니다.

// 요청할 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": "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() }

// 요청에서 데이터 가져 오기

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

// 요청에서 이미지 또는 비디오와 같은 다운로드 콘텐츠를 가져옵니다.

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

목표 C

매개 변수와 함께 API를 게시하고 URL로 유효성을 검사하여 json
응답 키가 상태 : "success"인 경우 탐색합니다 .

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 응답 : { "status": "success", "user_id": "58", "user_name": "dilip", "result": "성공적으로 로그인되었습니다"} 작동 코드

**

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.