Разработка iPhone/iPod touch приложений: Загрузка файлов из iPhone на Apache сервер POST методом.

Загрузить файл с внешнего источника в приложение не составит труда. А вот при загрузке в обратном направлении, многие могут столкнуться с трудностями. Сегодня мы будем загружать файл из ресурсов приложения на apache сервер методом POST.
Предположим что у нас в ресурсах находится изображения, которое необходимо загрузить на сервер.

Серверная часть

Нам понадобится apache сервер. В DocumentRoot создадим 2 файла и одну папку. Файл index.php нужен только для тестирования работы серверной части из браузера. В этот файл пишем HTML код формы для отправки.


<form enctype="multipart/form-data" action="uploader.php" method="POST">
  <input type="hidden" name="MAX_FILE_SIZE" value="100000" />
  Choose a file to upload: <input name="uploadedfile" type="file" />
  <br />
  <input type="submit" value="Upload File" />
</form>

Второй файл будет отвечать за прием изображения. Записать принятое изображение он должен в папку uploads. Ее нужно создать и правильно задать права на запись. Скрипт, отвечающий за прием файлов uploader.php:


$target_path = "uploads/";

$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);

if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
    echo "The file ".  basename( $_FILES['uploadedfile']['name']).
    " has been uploaded";
} else{
    echo "There was an error uploading the file, please try again!";
}

В случае возникновения ошибки, скрипт вернет сообщение “There was an error uploading the file, please try again!”. Работу сервера проверяем при помощи браузера. Вызываем скрипт index.php и в форму добавляем небольшой файл. После того как форма будет отправлена, файл должен быть загружен в папку uploads.

Клиентская часть

Для начала необходимо добавить изображения в ресурсы. А после этого можно приступать к написанию кода. У меня файл изображения имеет название “stamp1.png”.

Создаем класс с именем FileUploader для работы с сервером. Для обработки ответа от сервера нам понадобится временная переменная. Листинг файла заголовка приведен ниже.


@interface FileUploader : NSObject {
    NSMutableData *responseData;
}

-(void) upload;

@end

Метод upload загружает файл.


-(void) upload{
  responseData=[[NSMutableData data] retain];
  NSURL *cgiUrl = [NSURL URLWithString:@"http://my.ip.net/~stanfy/uploader.php"];
  NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:cgiUrl];

  //adding header information:
  [postRequest setHTTPMethod:@"POST"];
  NSString *stringBoundary = [NSString stringWithString:@"jhhsdfDGFJhsdfHDFgDSFfdsf"];
  NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
  [postRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];
  NSString *edFileName = @"stamp1.png";
  //setting up the body:
  NSMutableData *postBody = [NSMutableData data];
  [postBody appendData:[[NSString stringWithFormat:@"\r\n\r\n--%@\r\n",stringBoundary]
                 dataUsingEncoding:NSUTF8StringEncoding]];
  [postBody appendData:[[NSString
    stringWithFormat:@"Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"%@\"\r\n",
    [edFileName lastPathComponent]] dataUsingEncoding:NSUTF8StringEncoding]];
  [postBody appendData:[[NSString stringWithString:@"Content-Type: image/png\r\n\r\n"]
          dataUsingEncoding:NSUTF8StringEncoding]];

  NSString *imagePath = [[[NSBundle mainBundle] resourcePath]
             stringByAppendingPathComponent:edFileName];
  [postBody appendData:[NSData dataWithContentsOfFile:imagePath]];
  [postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary]
         dataUsingEncoding:NSUTF8StringEncoding]];
  [postRequest setHTTPBody:postBody];
  [[NSURLConnection alloc] initWithRequest:postRequest delegate:self];
}

Важно добавлять все параметры запроса в определенной последовательности. И последнее, это методы делегата соединения для отображения ответа от сервера.


#pragma mark -
#pragma mark Connection Delegate Methods
#pragma mark -

- (void)connection:(NSURLConnection *)connection
     didReceiveResponse:(NSURLResponse *)response {
	[responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection
     didReceiveData:(NSData *)data {
	[responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection
     didFailWithError:(NSError *)error {
    [responseData release];
    NSLog(@"Error");
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
	NSString *responseString = [[NSString alloc]
            initWithData:responseData encoding:NSUTF8StringEncoding];
	NSLog(@"Response %@", responseString);
    [responseData release];
    [responseString release];
}

Вот и все. Осталось только вызвать метод upload и файл будет загружен. Я не стану описывать структуру POST запроса, так как это тема совсем другой статьи. Этот пример поможет разобраться как отправить файл на сервер. Данные отправляются так же, как из браузера.

Комментарии

Shmidt

в 15:38, 04.09.2009

“…И последнее, это методы делегата соединения для отображения ответа от сервера…”
а по точнее можно? куда это писать???

SantaClaus

в 13:35, 19.09.2009

Насколько я понимаю, то писать надо в тот же файл в котором находится метод -(void) upload;

berec

в 13:30, 05.01.2010

спасибо

Оставить комментарий