İOS'ta HTTP POST isteği gönderme


86

Geliştirdiğim iOS uygulamasıyla bir HTTP Postası göndermeye çalışıyorum ancak yanıt olarak bir kod 200 alsam da (url bağlantısından) push sunucuya asla ulaşmıyor. Sunucudan hiçbir zaman yanıt alamıyorum ve sunucu gönderilerimi algılamıyor (sunucu android'den gelen gönderileri algılamıyor)

ARC kullanıyorum ama pd ve urlConnection'ı güçlü olarak ayarladım.

Bu, isteği göndermek için kodum

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

bu benim temsilci için kodum

#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

Konsol her zaman aşağıdaki satırları ve yalnızca aşağıdaki satırları yazdırır:

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

Yanıtlar:


188

Aşağıdaki kod, POSTyöntemi kullanan basit bir örneği açıklar . ( Verileri POSTyönteme göre nasıl geçirebilirim )

Burada POST yönteminin nasıl kullanılabileceğini anlatıyorum.

1. Posta dizesini gerçek kullanıcı adı ve parolayla ayarlayın.

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

2. Posta dizesini NSASCIIStringEncodingve ayrıca NSData biçiminde göndermeniz gereken posta dizesini kullanarak kodlayın .

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

Verilerinizin gerçek uzunluğunu göndermeniz gerekir. Gönderi dizesinin uzunluğunu hesaplayın.

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

3.HTTP Method, http başlık alanı ve post dizesinin uzunluğu gibi tüm özelliklere sahip bir URL isteği oluşturun . URLRequestNesne oluşturun ve onu başlatın.

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

Verileri bu isteğe göndereceğiniz URL'yi ayarlayın.

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

Şimdi, HTTP yöntemini ( POST veya GET ) ayarlayın. Bu satırları kodunuzda olduğu gibi yazın.

[request setHTTPMethod:@"POST"]; 

HTTPBaşlık alanını gönderi verilerinin uzunluğu ile ayarlayın .

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

Ayrıca HTTP üstbilgisi Alanı için Kodlanmış değeri ayarlayın.

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

Set HTTPBodypostData ile URLRequest arasında.

[request setHTTPBody:postData];

4. Şimdi, URLConnection nesnesini oluşturun. URLRequest ile başlatın.

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

Başlatılan url bağlantısını döndürür ve url isteği için verileri yüklemeye başlar. Aşağıdaki gibi URLsadece if / else ifadesini kullanarak bağlantınızın doğru yapılıp yapılmadığını kontrol edebilirsiniz .

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

5. HTTP isteğinden verileri almak için, URLConnection Sınıf Başvurusu tarafından sağlanan temsilci yöntemlerini kullanabilirsiniz. Temsilci yöntemleri aşağıdaki gibidir.

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

Ayrıca yöntem için Bu ve Bu dokümantasyona bakınPOST .

Ve burada HTTPPost Metodunun kaynak kodu ile en iyi örnek .


1
Ayrıca herhangi bir önbelleğe alma olup olmadığını kontrol edin. Bu, sunucuda hiçbir şey olmadan neden '200' aldığınızı açıklar.
Jelle 13

"Nsurlconnection cache policy" için stackoverflow.com/questions/405151/… ve / veya google'da kabul edilen yanıtı kontrol edin
Jelle 13

1
Cevap pek çok kez kabul edilmiş olsa da, bu cevapta verilen kodun bir takım göze batan sorunları vardır ve pratikte sıkıntılı olacaktır.
CouchDeveloper

1
@iPatel Ancak yukarıda verilen posta yöntemi kodunu kullanarak görüntü verilerini gönderebilir miyiz?
iHulk

1
Ne yazık ki bu kod yanlıştır ve enjeksiyon saldırılarına meyillidir. Kullanıcının şifresinde bir "&" karakteri varsa, diğer tüm karakterler ek bir POST parametresi olarak ayrıştırılacaktır. Kasıtlı manipülasyon mümkündür.
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

Neden olduğundan emin değilim, ancak aşağıdaki yöntemi yorumladığım anda işe yarıyor:

connectionDidFinishDownloading:destinationURL:

Ayrıca, bazı indirme bilgileri istemediğiniz sürece NSUrlConnectionDownloadDelegate protokolünden, yalnızca NSURLConnectionDataDelegate'den gelen yöntemlere ihtiyacınız olduğunu sanmıyorum.


İndirme bilgilerini istiyorum, bu yüzden connectionDidFinishDownloading: destinationURL:
Daan Luttik

1
Görünüşe göre NSURLConnectionDownloadDelegate yalnızca Gazetelik uygulamalarında çalışıyor .... En azından bu ileti dizisi şöyle diyor: stackoverflow.com/questions/6735121/…
nickygerritsen

2

Günlük kitaplığımda kullandığım yöntem: https://github.com/goktugyil/QorumLogs

Bu yöntem, Google Formlar içindeki html formlarını doldurur. Umarım Swift kullanan birine yardımcı olur.

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

İOS'ta HTTP POST isteği gönderme (Hedef 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];
}

Bu yeni ... Sorunuz gönderildikten 4 yıl sonra yanıt
alınıyor

Bu "örnek sonrası" işlevi, Response : p @DaanLuttik
Ronny Morán

1

Swift 3 veya 4'ü kullanarak sunucu iletişimi için bu http talebine erişebilirsiniz.

// POST verilerinin talep edilmesi için

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

// İstekten veri almak için

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

// İstekten resim veya video gibi indirme içeriğini almak için

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

Hedef C

Şu
durumdaki json yanıt anahtarının "başarılı" olup olmadığını görmek için API'yi parametrelerle yayınlayın ve url ile doğrulayın

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 Yanıtı : {"status": "success", "user_id": "58", "user_name": "dilip", "result": "Başarıyla giriş yaptınız"} Çalışma kodu

**

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.