ios Cargar imagen y texto mediante HTTP POST

96

Gracias por leer.

Soy nuevo en iOS y estoy tratando de cargar una imagen y un texto usando multi-part form encodingiOS.

El curlequivalente es algo como esto:curl -F "param1=value1" -F "[email protected]" "http://some.ip.address:5000/upload"

El curlcomando anterior devuelve la respuesta correcta esperada enJSON.

Problema: sigo recibiendo una solicitud HTTP 400, lo que significa que estoy haciendo algo mal al redactar el cuerpo de HTTP POST.

Lo que hice: Para alguna referencia, probé la aplicación iOS de Flickr API "¡El tamaño de la publicación es demasiado grande!" y Objetivo C: ¿Cómo cargar imágenes y texto usando HTTP POST? . Pero sigo obteniendo un HTTP 400.

Probé ASIHttpRequestpero tuve un problema diferente allí (nunca se llamó a la devolución de llamada). Pero no investigué más sobre eso, ya que escuché que el desarrollador dejó de admitir la biblioteca: http://allseeing-i.com/[request_release] ;

¿Podría alguien ayudarme?

Sagar Hatekar
fuente
3
Usé NSURLConnection. stackoverflow.com/questions/8042360/…
XJones
Gracias por el enlace. De hecho, eso todavía me da un error 400. Imprimí el cuerpo de la publicación http, y en lugar de la imagen, todo lo que veo son dos caracteres basura. Entonces, cuando agrega imageData, es de tipo NSData, ¿debería ser una cadena codificada en base64 en su lugar? Por cierto, mi imageToPost es de tipo UIImage.
Sagar Hatekar
1
Ese código tal como está escrito funciona en mi aplicación para publicar imágenes en nuestro servidor web (Linux / PHP). La imagen es un UIImage.
XJones

Respuestas:

223

Aquí está el código de mi aplicación para publicar una imagen en nuestro servidor web:

// Dictionary that holds post parameters. You can set your post parameters that your server accepts or programmed to accept.
NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
[_params setObject:[NSString stringWithString:@"1.0"] forKey:[NSString stringWithString:@"ver"]];
[_params setObject:[NSString stringWithString:@"en"] forKey:[NSString stringWithString:@"lan"]];
[_params setObject:[NSString stringWithFormat:@"%d", userId] forKey:[NSString stringWithString:@"userId"]];
[_params setObject:[NSString stringWithFormat:@"%@",title] forKey:[NSString stringWithString:@"title"]];

// the boundary string : a random string, that will not repeat in post data, to separate post data fields.
NSString *BoundaryConstant = [NSString stringWithString:@"----------V2ymHFg03ehbqgZCaKO6jy"];

// string constant for the post parameter 'file'. My server uses this name: `file`. Your's may differ 
NSString* FileParamConstant = [NSString stringWithString:@"file"];

// the server url to which the image (or the media) is uploaded. Use your server url here
NSURL* requestURL = [NSURL URLWithString:@""]; 

// create request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];                                    
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];

// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", BoundaryConstant];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];

// post body
NSMutableData *body = [NSMutableData data];

// add params (all params are strings)
for (NSString *param in _params) {
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"%@\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}

// add image data
NSData *imageData = UIImageJPEGRepresentation(imageToPost, 1.0);
if (imageData) {
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"Content-Type: image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:imageData];
    [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}

[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];

// setting the body of the post to the reqeust
[request setHTTPBody:body];

// set the content-length
NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long) [body length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];

// set URL
[request setURL:requestURL];
XJones
fuente
24
Para las personas que se refieren a este código: "BoundaryConstant" es básicamente la variable "boundary" que es esencialmente aleatoria (NSString *), "FileParamConstant" es básicamente su "filename.jpg".
Sagar Hatekar
8
Gracias por publicar, esto es muy útil. Que algún día encuentres una mina de platino como recompensa por tu genialidad.
Ian
1
Entre la gran cantidad de publicaciones sobre el tema, esta fue la mejor. Gracias hombre.
tompave
1
Probé este código pero creo que se pierde la instrucción para iniciar la solicitud. ¿Alguien puede decirme qué es en este caso?
Gannicus
3
@Gannicus, para no alargarlo demasiado, será algo así como: [NSURLConnection sendAsynchronousRequest: cola de solicitud: [NSOperationQueue mainQueue] CompletionHandler: ^ (NSURLResponse * respuesta, NSData * datos, NSError * connectionError) {}];
Eric
68

La respuesta de XJones funcionó a las mil maravillas .

Pero no se menciona / variables declaradas _params, BoundaryConstanty requestURL. Entonces, pensé en publicar esa parte como un complemento a su publicación, para que pueda ayudar a otros en el futuro.

// Dictionary that holds post parameters. You can set your post parameters that your server accepts or programmed to accept.
NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
[_params setObject:[NSString stringWithString:@"1.0"] forKey:[NSString stringWithString:@"ver"]];
[_params setObject:[NSString stringWithString:@"en"] forKey:[NSString stringWithString:@"lan"]];
[_params setObject:[NSString stringWithFormat:@"%d", userId] forKey:[NSString stringWithString:@"userId"]];
[_params setObject:[NSString stringWithFormat:@"%@",title] forKey:[NSString stringWithString:@"title"]];

// the boundary string : a random string, that will not repeat in post data, to separate post data fields.
NSString *BoundaryConstant = [NSString stringWithString:@"----------V2ymHFg03ehbqgZCaKO6jy"];

// string constant for the post parameter 'file'. My server uses this name: `file`. Your's may differ 
NSString* FileParamConstant = [NSString stringWithString:@"file"];

// the server url to which the image (or the media) is uploaded. Use your server url here
NSURL* requestURL = [NSURL URLWithString:@""]; 

Como mencioné antes, esta no es una respuesta en sí misma, solo un complemento de la publicación de XJones .

Sunil
fuente
@sunil: también quiero enviar 2 archivos de audio con imagen y algunas cadenas al servidor. Por favor sugiéreme cómo hacerlo.
Mak13
9

Para envío de imagen de publicación http y nombre de usuario y contraseña a través del método de publicación

 NSString *str=[NSString stringWithFormat:@"%@registration.php",appdel.baseUrl];
 NSString *urlString = [NSString stringWithFormat:@"%@",str];

 NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
 [request setURL:[NSURL URLWithString:urlString]];
 [request setHTTPMethod:@"POST"];
 NSMutableData *body = [NSMutableData data];
 NSString *boundary = @"---------------------------14737809831466499882746641449";
 NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
 [request addValue:contentType forHTTPHeaderField: @"Content-Type"];

 [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"a.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[NSData dataWithData:imgData]];
 [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

 //  parameter username

 [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"username\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

 [body appendData:[userName.text dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];


 //  parameter token
 [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"email\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

 [body appendData:[eMail.text dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];


 // parameter method
 [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"pass\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

 [body appendData:[passWord.text dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];


 //parameter method
 NSLog(@"%@",countryCode);
 [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"country\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

 [body appendData:[countryCode dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

 // close form
 [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];


 // setting the body of the post to the reqeust
 [request setHTTPBody:body];


 NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
 // NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
 NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableLeaves error:nil];
 Nslog(@"%@",dict);
 //
mahesh chowdary
fuente
Intenté esto pero mi (nsmutabledata) está siendo nulo al final del tiempo de setHTTPBody. ¿Me he perdido algo?
jayraj mg
@ jayrajm.g. para mí está funcionando. puede ser su problema de servicio web, ¿por qué estás renunciando a votar?
Mahesh Chowdary
6

Utilice AFNetworking; Coloque otros parámetros en el diccionario de parámetros y agregue los datos de imagen en los datos del formulario.

//Upload Image Using AFNetworking

-(BOOL)uploadImageAFNetworkingWithURL:(NSString *)path andImage:(UIImage *)image andImageNameWithExtension:(NSString *)strImageName andParamDict:(NSDictionary *)dictParam andKeyForUploadingImage:(NSString *)keyUplaodImg{

    NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
    NSString *strError = EMPTY_STRING;

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
     manager.requestSerializer = [AFJSONRequestSerializer serializer];
    [manager POST:path parameters:dictParam constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

        [formData appendPartWithFileData:imageData name:keyUplaodImg fileName:strImageName mimeType:@"image/jpeg"];

    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"success = %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"error = %@", error);
        NSLog(@"Response = %@", operation);
        [strError stringByAppendingString:STR_ERR_MESSAGE];
    }];
    if(strError.length>0){
        return NO;
    }else{
        return YES;
    }
}
Harish Pathak
fuente
obteniendo un problema para el parámetro de diccionario anidado, el formato json no recibe el formato correcto en el extremo del servidor. ¿¿Alguna ayuda??
UserDev
3

Aquí está mi biblioteca de kit de red similar para cargar archivos como formulario multiparte:

WebRequest *request = [[WebRequest alloc] initWithPath:@"...documents/create.json"];

// optional attributes
request.delegate = delegate;
request.notificationName = @"NotificationDocumentUploaded";
request.queue = myQueue;

NSMutableData *body = [NSMutableData data];
NSString *boundary = @"TeslaSchoolProjectFormBoundary";

[body appendPartName:@"document[name]" value:@"Test" boundary:boundary];
[body appendPartName:@"document[description]" value:@"This is a description" boundary:boundary];
[body appendPartName:@"document[category]" value:@"Drama" boundary:boundary];
...
[body appendPartName:@"commit" value:@"Save" boundary:boundary];
NSData *fileData = [[NSData alloc] initWithContentsOfURL:someFileURL];
[body appendPartFile:fileName name:@"document[file]" data:fileData mimeType:mimeType boundary:boundary];
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:body];

NSString *bodyLength = [NSString stringWithFormat:@"%lu",(unsigned long)[body length]];
[request addValue:bodyLength forHTTPHeaderField:@"Content-Length"];
[request setValue:[NSString stringWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"];


// optional values
[request addValue:@"gzip,deflate,sdch" forHTTPHeaderField:@"Accept-Encoding"];
[request addValue:@"max-age=0" forHTTPHeaderField:@"Cache-Control"];
[request addValue:@"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" forHTTPHeaderField:@"Accept"];
[request addValue:@"en-US,en;q=0.8,hr;q=0.6,it;q=0.4,sk;q=0.2,sl;q=0.2,sr;q=0.2" forHTTPHeaderField:@"Accept-Language"];


[request setHTTPMethod:@"POST"];
[WebRequestProcessor process:request];

Utilice el delegado para notificar el progreso de la carga.

Utilice el nombre de notificación para notificar cuando la solicitud ha finalizado.

Utilizar el cola para agregar esta solicitud a su cola de operaciones para que se procese en el momento adecuado.

Prcela
fuente
1
Una biblioteca sin prefijo de clase, seguro que no en mis proyectos.
vikingosegundo
1

aquí está el código rápido de trabajo traducido del código proporcionado por @xjones. Muchas gracias por tu ayuda, compañero. La tuya fue la única forma que funcionó para mí. Usé este método para enviar 1 imagen y otro parámetro a un servicio web realizado en asp.net


                    let params = NSMutableDictionary()

                    let boundaryConstant  = "----------V2y2HFg03eptjbaKO0j1"

                    let file1ParamConstant = "file1"
                    params.setObject(device_id!, forKey: "deviceID")

                    let requestUrl = NSURL(string: "\(siteurl):\(port)/FileUpload/Upload")

                    let request = NSMutableURLRequest()

                    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
                    request.HTTPShouldHandleCookies=false
                    request.timeoutInterval = 30
                    request.HTTPMethod = "POST"

                    let contentType = "multipart/form-data; boundary=\(boundaryConstant)"

                    request.setValue(contentType, forHTTPHeaderField: "Content-Type")

                    let body = NSMutableData()

                    // parameters

                    for param in params {

                    body.appendData("--\(boundaryConstant)\r\n" .dataUsingEncoding(NSUTF8StringEncoding)! )
                    body.appendData("Content-Disposition: form-data; name=\"\(param)\"\r\n\r\n" .dataUsingEncoding(NSUTF8StringEncoding)!)
                    body.appendData("\(param.value)\r\n" .dataUsingEncoding(NSUTF8StringEncoding)!)

                    }
                    // images

                    // image begin
                    body.appendData("--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

                    body.appendData("Content-Disposition: form-data; name=\"\(file1ParamConstant)\"; filename=\"image.jpg\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
                    body.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

                    body.appendData(passportImageData)
                    body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

                    // image end



                    body.appendData("--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

                    request.HTTPBody  = body
                    let postLength = "\(body.length)"
                    request.setValue(postLength, forHTTPHeaderField: "Content-Length")
                    request.URL = requestUrl

                    var serverResponse = NSString()

                    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
                        data, response, error in

                        if error != nil
                        {
                            print("error=\(error)")
                            return
                        }


                        print("response = \(response)")


                        let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
                        print("responseString = \(responseString!)")
                        serverResponse = responseString!


                        }

                            task.resume()
Hammadzafar
fuente
1

Aquí hay una versión Swift. Tenga en cuenta que si no desea enviar datos del formulario, es importante enviar el límite del formulario vacío. Flask, en particular, espera datos de formulario seguidos de datos de archivo y no se completará request.filessin el primer límite.

  let composedData = NSMutableData()

  // Set content type header
  let BoundaryConstant = "--------------------------3d74a90a3bfb8696"
  let contentType = "multipart/form-data; boundary=\(BoundaryConstant)"
  request.setValue(contentType, forHTTPHeaderField: "Content-Type")

  // Empty form boundary
  composedData.appendData("--\(BoundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

  // Build multipart form to send image
  composedData.appendData("--\(BoundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
  composedData.appendData("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpg\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
  composedData.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
  composedData.appendData(rawData!)
  composedData.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
  composedData.appendData("--\(BoundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

  request.HTTPBody = composedData

  // Get content length
  let length = "\(composedData.length)"
  request.setValue(length, forHTTPHeaderField: "Content-Length")
Eric Conner
fuente
1

Cargue la imagen con los datos del formulario usando la clase NSURLConnection en Swift 2.2 :

    func uploadImage(){
        let imageData = UIImagePNGRepresentation(UIImage(named: "dexter.jpg")!)

        if imageData != nil{
            let str = "https://staging.mywebsite.com/V2.9/uploadfile"
            let request = NSMutableURLRequest(URL: NSURL(string:str)!)
            request.HTTPMethod = "POST"

            let boundary = NSString(format: "---------------------------14737809831466499882746641449")

            let contentType = NSString(format: "multipart/form-data; boundary=%@",boundary)
            request.addValue(contentType as String, forHTTPHeaderField: "Content-Type")

            let body = NSMutableData()

            // append image data to body
            body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
            body.appendData(NSString(format:"Content-Disposition: form-data; name=\"file\"; filename=\"img.jpg\"\\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
            body.appendData(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
            body.appendData(imageData!)
            body.appendData(NSString(format: "\r\n--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)

            request.HTTPBody = body

            do {
                let returnData = try NSURLConnection.sendSynchronousRequest(request, returningResponse: nil)
                let returnString = NSString(data: returnData, encoding: NSUTF8StringEncoding)
                print("returnString = \(returnString!)")
            }
            catch let  error as NSError {
                print(error.description)
            }
        }
    }

Nota: Utilice siempre el sendAsynchronousRequestmétodo en lugar de sendSynchronousRequestcargar / descargar datos para evitar bloquear el hilo principal. Aquí utilicé sendSynchronousRequest solo con fines de prueba.

Nitesh Borad
fuente
0

Puedo mostrarte un ejemplo de cómo subir un archivo .txt a un servidor con NSMutableURLRequesty NSURLSessionUploadTaskcon la ayuda de un script php .

-(void)uploadFileToServer : (NSString *) filePath
{
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://YourURL.com/YourphpScript.php"]];
[request setHTTPMethod:@"POST"]; 
[request addValue:@"File Name" forHTTPHeaderField:@"FileName"];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject];

NSURLSessionUploadTask* uploadTask = [defaultSession uploadTaskWithRequest:request fromFile:[NSURL URLWithString:filePath] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
                                      {
                                          NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                          if (error || [httpResponse statusCode]!=202)
                                          {

                                              //Error
                                          }
                                          else
                                          {
                                             //Success
                                          }
                                          [defaultSession invalidateAndCancel];
                                      }];
[uploadTask resume];
}

secuencia de comandos php

<?php 
$request_body = @file_get_contents('php://input');
foreach (getallheaders() as $name => $value) 
{
    if ($FileName=="FileName") 
    {
        $header=$value;
        break;
    }
}   
$uploadedDir = "directory/";
@mkdir($uploadedDir);
file_put_contents($uploadedDir."/".$FileName.".txt",
$request_body.PHP_EOL, FILE_APPEND);
header('X-PHP-Response-Code: 202', true, 202);  
?>       
Nikhil Augustine
fuente
0
use below code. it will work fine for me.

+(void) sendHttpRequestWithArrayContent:(NSMutableArray *) array 
ToUrl:(NSString *) strUrl withHttpMethod:(NSString *) strMethod 
withBlock:(dictionary)block
{
if (![Utility isConnectionAvailableWithAlert:TRUE])
{
    [Utility showAlertWithTitle:@"" andMessage:@"No internet connection available"];
}


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

[request setURL:[NSURL URLWithString:strUrl]];
[request setTimeoutInterval:120.0];
[request setHTTPMethod:strMethod];

NSString *boundary = @"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];

NSMutableData *body=[[NSMutableData alloc]init];

for (NSMutableDictionary *dict in array)
{
    if ([[dict valueForKey:[[dict allKeys]objectAtIndex:0]] isKindOfClass:[NSString class]])
    {
        [body appendData:[self contentDataFormStringWithValue:[dict valueForKey:[[dict allKeys]objectAtIndex:0]] withKey:[[dict allKeys]objectAtIndex:0]]];
    }
    else if ([[dict valueForKey:[[dict allKeys]objectAtIndex:0]] isKindOfClass:[UIImage class]])
    {
        [body appendData:[self contentDataFormImage:[dict valueForKey:[[dict allKeys]objectAtIndex:0]] withKey:[[dict allKeys]objectAtIndex:0]]];
    }
    else if ([[dict valueForKey:[[dict allKeys]objectAtIndex:0]] isKindOfClass:[NSMutableDictionary class]])
    {
        [body appendData:[self contentDataFormStringWithValue:[dict valueForKey:[[dict allKeys]objectAtIndex:0]] withKey:[[dict allKeys]objectAtIndex:0]]];
    }
    else
    {
        NSMutableData *dataBody = [NSMutableData data];
        [dataBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [dataBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"ipodfile.jpg\"\r\n",@"image"] dataUsingEncoding:NSUTF8StringEncoding]];
        [dataBody appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

        [dataBody appendData:[dict valueForKey:[[dict allKeys]objectAtIndex:0]]];

        [body appendData:dataBody];
    }
}

[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:body];

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
 {
     if (!data) {
         NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
          [dict setObject:[NSString stringWithFormat:@"%@",SomethingWentWrong] forKey:@"error"];
         block(dict);
         return ;
     }
     NSError *error = nil;
    // NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
     NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
     NSLog(@"%@",dict);
     if (!dict) {
         NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
         [dict setObject:ServerResponceError forKey:@"error"];
         block(dict);
         return ;
     }
     block(dict);

 }];

}
+(NSMutableData*) contentDataFormStringWithValue:(NSString*)strValue 
withKey:(NSString *) key
{
NSString *boundary = @"---------------------------14737809831466499882746641449";
NSMutableData *data=[[NSMutableData alloc]init];
[data appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[[NSString stringWithFormat:@"%@",strValue] dataUsingEncoding:NSUTF8StringEncoding]];  // title
return data;
}

+(NSMutableData*) contentDataFormImage:(UIImage*)image withKey:
(NSString *) key
{
NSString *boundary = @"---------------------------14737809831466499882746641449";
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"ipodfile.jpg\"\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
NSData *imageData=UIImageJPEGRepresentation(image, 0.40);
[body appendData:imageData];

return body;
}
herry.master
fuente