Subir una imagen del iPhone al servidor con Objective C



Learn-Objective-C
Después de buscar bastante por Google conseguí encontrar la forma de subir una imagen (cualquier archivo para el caso) desde el iPhone a un servidor remoto. Es una función simple que puede ser incluida y utilizada en todos los proyectos. En mi caso, el servidor tiene un script PHP.

Así es cómo se utiliza la función:

// campos de formulario, campos y valores
NSArray *formfields = [NSArray arrayWithObjects:@"nombre", @"fecha", @"titulo", @"comentarios", nil];
NSArray *formvalues = [NSArray arrayWithObjects:@"NecsaL Blog", @"23-03-2013", @"Foto de prueba", @"Comentario de la foto", nil];
NSDictionary *textos = [NSDictionary dictionaryWithObjects:formvalues forKeys:formfields];

// si hay varias imagenes en el formulario
NSArray *imagenes = [NSArray arrayWithObjects:@"image1.png", @"image2.png", nil];

// enviar el formulario
[self doPostWithText:textos andImage:imagenes];

Esta es la función definida como doPostWithText:andImage:

- (void) doPostWithText:(NSDictionary *)textos andImage:(NSArray *)imagenes 
{
    NSString *urlString = @"http://misitio.com/miscript.php";
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"POST"];

    NSMutableData *body = [NSMutableData data];

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

	// añadimos las imagenes
	for (int i=0; i<[imagenes count]; i++) {
		[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
		[body appendData:[[NSString stringWithFormat:@"Content-Disposition: attachment; name=\"imagen%d\"; filename=\"%@\"\r\n", i, [imagenes objectAtIndex:i]] dataUsingEncoding:NSUTF8StringEncoding]];
		[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
		[body appendData:[NSData dataWithData:UIImageJPEGRepresentation([UIImage imageNamed:[imagenes objectAtIndex:i]], 90)]];
		[body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

	}

	// añadimos los campos y los valores
	for (id key in textos) {
		[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
		[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
		[body appendData:[[NSString stringWithString:[textos objectForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]];
		[body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
	}

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

    // seteamos el body en el request
    [request setHTTPBody:body];

    // envía la request (envia el formulario) and obtiene la respuesta de script PHP en este caso
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

    NSLog(@"%@", returnString);
}

Por el lado de PHP que recibirá los datos de esta manera:

– Tendremos los campos y sus valores en el $_POST

Array
(
    [nombre] => NecsaL Blog
    [fecha] => 23-03-2013
    [titulo] => Foto de prueba
    [comentario] => Comentario de la foto
)

– Y las imágenes en el $_FILES

Array
(
    [imagen0] => Array
        (
            [name] => imagen1.png
            [type] => application/octet-stream
            [tmp_name] => /junk/temp/phpsKiVxx
            [error] => 0
            [size] => 21602
        )

    [imagen1] => Array
        (
            [name] => imagen2.png
            [type] => application/octet-stream
            [tmp_name] => /junk/temp/phpNVGDoB
            [error] => 0
            [size] => 4520
        )

)

Espero que este snippet os sea de ayuda. Para cualquier pregunta no dudéis en comentar.

One Response

  1. Juan P. Pestana diciembre 30, 2014