74

Я пытаюсь отправить HTTP-сообщение с приложением iOS, которое я разрабатываю, но push никогда не достигает сервера, хотя я получаю код 200 как ответ (от urlconnection). Я никогда не получаю ответа от сервера, и сервер не обнаруживает мои сообщения (сервер обнаруживает сообщения, исходящие от android)Отправка запроса HTTP POST на iOS

Я использую 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 <> 

ответ

175

Следующий код описывает простой пример с использованием метода POST. (Как можно передавать данные по POST метод)

Здесь я опишу, как можно использовать метод POST.

1. Установить строку с указанием фактического имени пользователя и пароля.

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

2. Encode пост строку с помощью NSASCIIStringEncoding, а также после строки вам необходимо отправить в формате NSData.

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

Необходимо отправить фактическую информацию. Вычислите длину строки сообщения.

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

3. Создать URLRequest со всеми свойствами, как HTTP метод, HTTP поля заголовка с длиной почтовой строки. Создайте объект URLRequest и инициализируйте его.

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

Укажите адрес, на который вы хотите отправить данные по этому запросу.

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

Установите HTTPBody в URLRequest с PostData.

[request setHTTPBody:postData]; 

4. Теперь создадим объект URLConnection. Инициализируйте его с помощью URLRequest.

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

Он возвращает инициализированное соединение с URL и начинает загружать данные для запроса URL. Вы можете проверить, выполнено ли соединение URL должным образом или нет, используя только if/else заявление, как показано ниже.

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

5. Для получения данных из запроса HTTP, вы можете использовать методы делегата, предоставляемые URLConnection Class Reference. Методы делегатов приведены ниже.

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

См такжеThisиThisдокументации для POST метода.

А вот лучший пример с исходным кодом HTTPPost Method.

+1

Также проверьте, нет ли кеширования. Это объясняет, почему вы получили «200», без чего-либо на сервере. – Jelle

+0

Проверьте принятый ответ http://stackoverflow.com/questions/405151/is-it-possible-to-prevent-an-nsurlrequest-from-caching-data-or-remove-cached-dat и/или google для «Политика кэширования nsurlconnection» – Jelle

+0

Большое вам спасибо, что я проверил столько потоков и это: http://yuvarajmanickam.wordpress.com/2012/10/17/nsurlconnection-basics-for-ios-beginners/ просто работал. –

1

Я не совсем уверен, почему, но как только я закомментировать следующий метод он работает:

connectionDidFinishDownloading:destinationURL: 

Кроме того, я не» Думаю, вам нужны методы из протокола NSUrlConnectionDownloadDelegate, только те из NSURLConnectionDataDelegate, если вы не хотите получить какую-либо информацию о загрузке.

+0

Мне нужна информация для загрузки, поэтому у меня есть функция connectionDidFinishDownloading: destinationURL: –

+1

Очевидно, NSURLConnectionDownloadDelegate работает только в приложениях Newsstand ... По крайней мере, это то, что говорит этот поток: http://stackoverflow.com/questions/6735121/ не удалось получить-destinationurl-data-in-connectiondidfinishdownloading-for-ios5 – nickygerritsen

1

Heres метод, который я использовал в моей библиотеке регистрации: https://github.com/goktugyil/QorumLogs

Этот метод заполняет HTML-формы внутри Google Forms. Надеюсь, это поможет кому-то, кто использует Свифт.

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

** Post 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 *[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 ответ: { "Статус" : «success», «user_id»: «58», «user_name»: «dilip», «result»: «Вы успешно вошли в систему»} Рабочий код

**

0

Отправка запроса HTTP POST на прошивке (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

Это новое ... Получение ответов через 4 года после публикации вашего вопроса: p –

+0

Эта функция «postexample» выполняется быстрее, чем [Response] (https : //stackoverflow.com/a/15749527/3400859): p @DaanLuttik –

0

Использование 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() 

} 
Смежные вопросы