Obiettivo C: come caricare immagini e testo tramite HTTP POST?

Ho creato con successo due metodi diversi in cui ognuno di essi può caricare un’immagine o un testo. Ma sto avendo problemi a scrivere un metodo che possa pubblicare sia testo che immagine contemporaneamente!

// Ecco il mio nuovo metodo, la strega ha lavorato bene grazie a @sgosha:

- (void) upload { NSString *urlString = @"http://www.examplescript.com"; NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; [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"]; // file NSData *imageData = UIImageJPEGRepresentation(imageView.image, 90); [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"Content-Disposition: attachment; name=\"userfile\"; filename=\".jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[NSData dataWithData:imageData]]; [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; // Text parameter1 NSString *param1 = @"parameter text"; [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"parameter1\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:param1] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; // Another text parameter NSString *param2 = @"Parameter 2 text"; [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"parameter2\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:param2] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; // close form [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; // set request body [request setHTTPBody:body]; //return and test NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding]; NSLog(@"%@", returnString); } 

// Vecchia domanda: ovviamente questo era troppo facile e non ha funzionato! Non ricevo alcun errore nella console o altro, e l’immagine viene caricata, ma il testo non viene inviato. Qualche idea?

Btw: lo script sul lato server è uno script php molto semplice.

Prova questo (MODIFICATO):

 NSMutableData *body = [NSMutableData data]; // file [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"Content-Disposition: attachment; name=\"userfile\"; filename=\".jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[NSData dataWithData:imageData]]; [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; // text parameter [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"parameter1\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[parameterValue1 dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; // another text parameter [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"parameter2\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[parameterValue2 dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; // close form [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; // set request body [request setHTTPBody:body]; 

Volevo anche caricare un’immagine insieme ad altri dati nello stesso POST, la maggior parte delle informazioni sul caricamento delle immagini è solo per caricare un’immagine da sola in una connessione server, ecco come ho risolto questo.

Questo è il PHP

 < ?php /* As you can see there are more values not only the image */ $variableOne = $_POST['variableOne']; $variableTwo = $_POST['variableTwo']; $variableThree = $_POST['variableThree']; $variableFour = $_POST['variableFour']; $variableFive = $_POST['variableFive']; $variableSix = $_POST['variableSix']; $variableSeven = $_POST['variableSeven']; $variableEight = $_POST['variableEight']; $variableNine = $_POST['variableNine']; $variableTen = $_POST['variableTen']; /* Our image */ $image = $_REQUEST['image']; /* This is for trying to get a unique name for the image file, since maybe you want to store large amount of images */ $currentDate = date("Ymd"); $name = "" . $currentDate . microtime() . rand(0, 999) . rand(0, 999) . rand(0, 999) . ".jpg"; /* * Here comes the image stuff */ if (file_exists($name)) { echo "File already exists"; } else { /* Decoding image */ $binary = base64_decode($image); /* Opening image */ $file = fopen($name, 'wb'); /* Writing to server */ fwrite($file, $binary); /* Closing image file */ fclose($file); echo "Added"; } } ?> 

Quindi, in Xcode, copia e incolla questo metodo (preso da Creazione di una stringa base 64 da NSData )

 - (NSString*)base64forData:(NSData*) theData { const uint8_t* input = (const uint8_t*)[theData bytes]; NSInteger length = [theData length]; static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4]; uint8_t* output = (uint8_t*)data.mutableBytes; NSInteger i; for (i=0; i < length; i += 3) { NSInteger value = 0; NSInteger j; for (j = i; j < (i + 3); j++) { value <<= 8; if (j < length) { value |= (0xFF & input[j]); } } NSInteger theIndex = (i / 3) * 4; output[theIndex + 0] = table[(value >> 18) & 0x3F]; output[theIndex + 1] = table[(value >> 12) & 0x3F]; output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '='; output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '='; } return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; } 

Nel file YourViewController.h

 @interface YourViewController : UIViewController { NSURLConnection *serverConnection; NSMutableData *returnData; } 

Questo è il codice di connessione del server

 NSURL *sendURL = [NSURL URLWithString:@"http://yourdomainname/imagefolder/phpscript.php"]; NSMutableURLRequest *sendRequest = [NSMutableURLRequest requestWithURL:sendURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30]; [sendRequest setHTTPMethod:@"POST"]; [sendRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; NSData *imageData = UIImageJPEGRepresentation(yourImage, 1.0); NSString *encodedString = [[self base64forData:imageData] stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"]; NSString *dataToSend = [[NSString alloc] initWithFormat:@"variableOne=%@&variableTwo=%@&variableThree=%@&variableFour=%@&variableFive=%@&variableSix=%@&variableSeven=%@&variableEight=%@&variableNine=%@&variableTen=%@&image=%@", valueOne, valueTwo, valueThree, valueFour, valueFive, valueSix, valueSeven, valueEight, valueNine, valueTen, encodedString]; [sendRequest setHTTPBody:[dataToSend dataUsingEncoding:NSUTF8StringEncoding]]; serverConnection = [[NSURLConnection alloc] initWithRequest:sendRequest delegate:self]; [serverConnection start]; 

Imposta metodi delegati per la connessione al server

 - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { returnData = [[NSMutableData alloc] init]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [returnData appendData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { if (connection == serverConnection) { NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding]; NSLog(@"Response: %@", responseString); if ([responseString isEqualToString:@"Added"]) { /* Make something on success */ } else { /* Make something else if not completed with success */ } } } - (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { /* Make something on failure */ } 

Questo codice funziona per me con 1 immagine e 7 altri parametri che utilizzano la richiesta POST

Assicurati di modificare i nomi delle variabili più i valori e anche il nome del parametro dell’immagine più ‘showPhoto’ che è il mio object IBOutlet UIImageView ‘nome’ mostra il nome del parametro URL.

NSString * str = @ ” http: //xxx.xxx.xxx.xx/xxxx/xxxxx/xxxxx.php? Action = add_place “; 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"]; NSData *imageData = UIImageJPEGRepresentation(_showPhoto.image, 90); [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"Content-Disposition: form-data; name=\"host_pic\"; filename=\"parkN.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:imageData]; [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=\"userID\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"17" 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=\"longitude\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"50.0011" 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=\"latitude\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"50.0011" 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=\"place_name\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"lahore" 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=\"place_description\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"lahore" 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=\"zip_code\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"123456" 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=\"phone_number\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"033333333" 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); 

Se vuoi nominare l’immagine:

  NSMutableString *nombreImagen= [[NSMutableString alloc]init]; [nombreImagen appendString:@"Content-Disposition: attachment; name=\"file\"; filename=\""]; [nombreImagen appendString:@"hoy"]; [nombreImagen appendString:@".jpg\"\r\n"]; ....... [body appendData:[[NSString stringWithString:nombreImagen] dataUsingEncoding:NSUTF8StringEncoding]];