74

Sto tentando di inviare un post HTTP con l'applicazione iOS che sto sviluppando ma il push non raggiunge mai il server anche se ottengo un codice 200 come risposta (dalla urlconnection). Non ottengo mai una risposta dal server né il server rileva i miei post (il server rileva i messaggi provenienti da Android)Invio di una richiesta POST HTTP su iOS

Io uso ARC ma ho impostato pd e urlConnection come forti.

Questo è il mio codice per l'invio della richiesta

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

questo è il mio codice per il delegato

#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 

La console di stampa sempre le seguenti linee e solo le seguenti righe:

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

risposta

175

Il seguente codice descrive un semplice esempio utilizzando il metodo POST. Come si può passare i dati da POST metodo)

Qui, mi descrivono come uno può usare del metodo POST.

1. Imposta stringa di post con nome utente e password effettivi.

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

2. Codifica la stringa post utilizzando NSASCIIStringEncoding e anche la stringa di posta è necessario inviare in formato NSData.

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

È necessario inviare la lunghezza effettiva dei dati. Calcola la lunghezza della stringa del post.

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

3. Creare un URLRequest con tutti gli immobili come HTTP metodo, http campo di intestazione con la lunghezza della stringa posta. Creare l'oggetto URLRequest e inizializzarlo.

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

Impostare l'URL per il quale si intende inviare i dati a tale richiesta.

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

Ora, impostare HTTP metodo (POST o GET). Scrivi queste righe così come sono nel tuo codice.

[request setHTTPMethod:@"POST"]; 

Set HTTP campo di intestazione con lunghezza dei dati post.

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

Impostare anche il valore Encoded per il campo dell'intestazione HTTP.

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

Impostare la HTTPBody del URLRequest con postData.

[request setHTTPBody:postData]; 

4. Ora, creare l'oggetto URLConnection. Inizializzalo con URLRequest.

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

Restituisce la connessione url inizializzata e inizia a caricare i dati per la richiesta di url. È possibile verificare che la connessione URL sia stata eseguita correttamente o non utilizzando solo se/o l'istruzione come di seguito.

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

5. per ricevere i dati dalla richiesta HTTP, è possibile utilizzare i metodi delegato forniti dal URLConnection classe di riferimento. I metodi delegati sono i seguenti.

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

riferimento ancheThiseThisdocumentazione per POST metodo.

Ed ecco miglior esempio con il codice sorgente di HTTPPost Method.

+1

Controllare anche se non è in corso la memorizzazione nella cache. Questo spiegherebbe perché hai ottenuto un '200', senza che nulla avvenga sul server. – Jelle

+0

Controlla la risposta accettata di http://stackoverflow.com/questions/405151/is-it-possible-to-prevent-an-nsurlrequest-from-caching-data-or-remove-cached-dat e/o google for "nsurlconnection cache policy" – Jelle

+0

Grazie mille ho controllato così tante discussioni e questo: http://yuvarajmanickam.wordpress.com/2012/10/17/nsurlconnection-basics-for-ios-beginners/ ha funzionato. –

1

io non sono davvero sicuro perché, ma appena io commento il seguente metodo funziona:

connectionDidFinishDownloading:destinationURL: 

Inoltre, I don' Penso che siano necessari i metodi del protocollo NSUrlConnectionDownloadDelegate, solo quelli di NSURLConnectionDataDelegate, a meno che non si desideri ottenere alcune informazioni di download.

+0

Desidero le informazioni di download, ecco perché ho la funzione connectionDidFinishDownloading: destinationURL: –

+1

Apparentemente NSURLConnectionDownloadDelegate funziona solo nelle app di Edicola .... Almeno questo è ciò che dice questo thread: http://stackoverflow.com/questions/6735121/ impossibile-to-get-destinationurl-data-in-connectiondidfinishdownloading-for-ios5 – nickygerritsen

1

Heres il metodo che ho usato nella mia libreria di registrazione: https://github.com/goktugyil/QorumLogs

Questo metodo riempie moduli HTML all'interno Moduli Google. Spero che aiuti qualcuno a usare 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) 
0
-(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]; 
} 
0

** Messaggio API con parametri e convalidare con l'URL per navigare se JSON chiave di risposta con stato: "successo"

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 *[email protected]"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 Risposta: { "status" : "success", "user_id": "58", "user_name": "dilip", "result": "L'accesso è stato eseguito correttamente"} Codice di lavoro

**

0

Invio di una richiesta HTTP POST su iOS (Objective 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]; 
} 
+0

Questo è nuovo ... Ottenere risposte 4 anni dopo la pubblicazione della domanda: p –

+0

Questa funzione "postexample" è più veloce di [Risposta] (https : //stackoverflow.com/a/15749527/3400859): p @DaanLuttik –

0

Utilizzando Swift 3 o 4 è possibile accedere a questi richiesta HTTP per la comunicazione sever.

// Per i dati POST di richiedere

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

// Per ottenere i dati dalla richiesta

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

// Per ottenere il download di contenuti come immagini o video da richiesta

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

}