Цель C: Как загрузить изображение и текст, используя HTTP POST?
Я успешно создал два разных метода, где каждый из них может загрузить изображение или текст. Но у меня проблемы с написанием метода, который может одновременно публиковать текст и изображение!
// Вот мой новый метод, с которым все работало отлично, благодаря @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);
}
// Старый вопрос: Очевидно, это было слишком просто и не работало! Я не получаю никакой ошибки в консоли или что-нибудь, и изображение загружается, но текст не отправляется. Есть идеи?
Кстати: серверный скрипт - это очень простой php-скрипт.
4 ответа
Попробуйте это (отредактировано):
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];
Я также хотел загрузить изображение вместе с другими данными в том же POST, большая часть информации о загрузке изображений предназначена только для загрузки изображения в одном подключении к серверу, вот как я решил это.
Это 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("Y-m-d");
$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";
}
}
?>
Затем в XCode скопируйте и вставьте этот метод (взят из Создание строки base-64 из 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];
}
В файле YourViewController.h
@interface YourViewController : UIViewController {
NSURLConnection *serverConnection;
NSMutableData *returnData;
}
Это код подключения к серверу
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];
Установить методы делегата для подключения к серверу
- (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 */
}
Этот код работает для меня с 1 изображением и 7 другими параметрами, используя запрос POST
Обязательно измените имена переменных плюс значения, а также имя параметра изображения плюс "showPhoto", которое является моим объектом IBOutlet UIImageView. "Name" показывает имя параметра 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);
Если вы хотите назвать изображение:
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]];