iphone objective-c ios

iphone - iOS: ¿cómo realizar una solicitud HTTP POST?



objective-c (7)

Aquí hay una respuesta actualizada para iOS7 +. Utiliza NSURLSession, el nuevo hotness. Descargo de responsabilidad, esto no se ha probado y se escribió en un campo de texto:

- (void)post { NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com/dontposthere"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; // Uncomment the following two lines if you''re using JSON like I imagine many people are (the person who is asking specified plain text) // [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; // [request addValue:@"application/json" forHTTPHeaderField:@"Accept"]; [request setHTTPMethod:@"POST"]; NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; }]; [postDataTask resume]; } -(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)( NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); }

O mejor aún, use AFNetworking 2.0+. Por lo general, yo subclase AFHTTPSessionManager, pero estoy poniendo todo esto en un método para tener un ejemplo conciso.

- (void)post { AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"https://example.com"]]; // Many people will probably want [AFJSONRequestSerializer serializer]; manager.requestSerializer = [AFHTTPRequestSerializer serializer]; // Many people will probably want [AFJSONResponseSerializer serializer]; manager.responseSerializer = [AFHTTPRequestSerializer serializer]; manager.securityPolicy.allowInvalidCertificates = NO; // Some servers require this to be YES, but default is NO. [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"username" password:@"password"]; [[manager POST:@"dontposthere" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) { NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"darn it"); }] resume]; }

Si está utilizando el serializador de respuestas JSON, responseObject será el objeto de la respuesta JSON (a menudo NSDictionary o NSArray).

Me estoy acercando al desarrollo de iOS y me gustaría tener una de mis primeras aplicaciones para realizar una solicitud HTTP POST.

Por lo que puedo entender, debo administrar la conexión que maneja la solicitud a través de un objeto NSURLConnection , lo que me obliga a tener un objeto delegado, que a su vez manejará los eventos de datos.

¿Podría alguien aclarar la tarea con un ejemplo práctico?

Debería contactar un punto final https enviando datos de autenticación (nombre de usuario y contraseña) y obteniendo una respuesta de texto sin formato.


Así es cómo funciona la solicitud POST HTTP para iOS 8+ usando NSURLSession:

- (void)call_PostNetworkingAPI:(NSURL *)url withCompletionBlock:(void(^)(id object,NSError *error,NSURLResponse *response))completion { NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; config.URLCache = nil; config.timeoutIntervalForRequest = 5.0f; config.timeoutIntervalForResource =10.0f; NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil]; NSMutableURLRequest *Req=[NSMutableURLRequest requestWithURL:url]; [Req setHTTPMethod:@"POST"]; NSURLSessionDataTask *task = [session dataTaskWithRequest:Req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error == nil) { NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; if (dict != nil) { completion(dict,error,response); } }else { completion(nil,error,response); } }]; [task resume]; }

Espero que esto satisfaga su siguiente requisito.


Pensé que actualizaría un poco esta publicación y diría que gran parte de la comunidad de iOS se ha trasladado a AFNetworking después de que se abandonara AFNetworking . Lo recomiendo altamente. Se trata de una excelente envoltura alrededor de NSURLConnection y permite llamadas asincrónicas y básicamente todo lo que pueda necesitar.


Puede usar NSURLConnection de la siguiente manera:

  1. Establezca su NSURLRequest : Use requestWithURL:(NSURL *)theURL para inicializar la solicitud.

    Si necesita especificar una solicitud POST y / o encabezados HTTP, use NSMutableURLRequest con

    • (void)setHTTPMethod:(NSString *)method
    • (void)setHTTPBody:(NSData *)data
    • (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
  2. Envíe su solicitud de 2 maneras usando NSURLConnection :

    • Sincrónicamente: (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error

      Esto devuelve una variable NSData que puede procesar.

      IMPORTANTE: recuerde iniciar la solicitud sincrónica en un hilo separado para evitar el bloqueo de la IU.

    • Asincrónicamente: (void)start

No olvides configurar el delegado de tu NSURLConnection para manejar la conexión de la siguiente manera:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { [self.data setLength:0]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d { [self.data appendData:d]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", @"") message:[error localizedDescription] delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles:nil] autorelease] show]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSString *responseText = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding]; // Do anything you want with it [responseText release]; } // Handle basic authentication challenge if needed - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { NSString *username = @"username"; NSString *password = @"password"; NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession]; [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; }


Xcode 8 y Swift 3.0

Usando URLSession:

let url = URL(string:"Download URL")! let req = NSMutableURLRequest(url:url) let config = URLSessionConfiguration.default let session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main) let task : URLSessionDownloadTask = session.downloadTask(with: req as URLRequest) task.resume()

Llamada de delegado de URLSession:

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { } func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) { print("downloaded /(100*writ/exp)" as AnyObject) } func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL){ }

Usando Block GET / POST / PUT / DELETE:

let request = NSMutableURLRequest(url: URL(string: "Your API URL here" ,param: param))!, cachePolicy: .useProtocolCachePolicy, timeoutInterval:"Your request timeout time in Seconds") request.httpMethod = "GET" request.allHTTPHeaderFields = headers as? [String : String] let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest) {data,response,error in let httpResponse = response as? HTTPURLResponse if (error != nil) { print(error) } else { print(httpResponse) } DispatchQueue.main.async { //Update your UI here } } dataTask.resume()

Trabajando bien para mí ... pruébalo 100% garantía de resultados


EDITAR: ASIHTTPRequest ha sido abandonado por el desarrollador. Todavía es muy buena OMI, pero probablemente deberías buscar en otro lado ahora.

Recomiendo usar la biblioteca ASIHTTPRequest si está manejando HTTPS. Incluso sin https proporciona una envoltura muy agradable para cosas como esta y, aunque no es difícil hacerlo tú mismo en lugar de http, solo creo que la biblioteca es agradable y una excelente manera de comenzar.

Las complicaciones HTTPS están lejos de ser triviales en varios escenarios, y si quiere ser robusto al manejar todas las variaciones, encontrará que la biblioteca ASI es una verdadera ayuda.


NOTA: Ejemplo de Pure Swift 3 (Xcode 8): Pruebe el siguiente código de muestra. Es el ejemplo simple de la función URLSession de URLSession .

func simpleDataRequest() { //Get the url from url string let url:URL = URL(string: "YOUR URL STRING")! //Get the session instance let session = URLSession.shared //Create Mutable url request var request = URLRequest(url: url as URL) //Set the http method type request.httpMethod = "POST" //Set the cache policy request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData //Post parameter let paramString = "key=value" //Set the post param as the request body request.httpBody = paramString.data(using: String.Encoding.utf8) let task = session.dataTask(with: request as URLRequest) { (data, response, error) in guard let _:Data = data as Data?, let _:URLResponse = response , error == nil else { //Oops! Error occured. print("error") return } //Get the raw response string let dataString = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) //Print the response print(dataString!) } //resume the task task.resume() }