iOS, загрузить файл с мультиформатными данными

Я хотел бы загрузить файл на HTTP-сервер. Я делаю это так:

NSString *boundary = @"*****"; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:@"http://someUploadScript.php"]]; [request setHTTPMethod:@"POST"]; NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; [request setValue:contentType forHTTPHeaderField: @"Content-Type"]; [request setValue:@"Keep-Alive" forHTTPHeaderField: @"Connection"]; dispatch_async(queue, ^{ NSMutableData *postbody = [NSMutableData data]; [postbody appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"video.mp4\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [postbody appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; NSString* outputPath = @"somePathToFile"; NSData *data = [NSData dataWithContentsOfFile:outputPath]; [postbody appendData:data]; [postbody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [postbody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [request setHTTPBody:postbody]; previousBytesWritten = 0; connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; }); 

Я хотел бы отправить некоторые дополнительные данные, например. подал «пользователь» с «userId» значением. Я хотел бы отправить какой-то массив вроде:

 video[user] = "userId" video[file] = //file bytes 

Я знаю, что могу сделать это, используя HTTP multipartform-data, но я действительно не знаю, как и я не понимаю, как это работает. Может кто-нибудь объяснить мне, как я могу это сделать и как это работает?

Попробуйте что-то вроде этого:

 NSMutableData *postbody = [NSMutableData data]; [postbody appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"video.mp4\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [postbody appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; NSString* outputPath = @"somePathToFile"; NSData *data = [NSData dataWithContentsOfFile:outputPath]; [postbody appendData:data]; [postbody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; // Adding one more field: // append boundary [postbody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; // setting up form-data header, if it is text no 'filename' needed [postbody appendData:[@"Content-Disposition: form-data; name=\"userId\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; // appending userId value [postbody appendData:[_userId dataUsingEncoding:NSUTF8StringEncoding]]; // Ending boundary [postbody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [postbody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [request setHTTPBody:postbody]; 

Также не забудьте добавить в заголовок HTTP-заголовок Content-Length.

AFNetowrking – это удобное решение на сегодняшний день. Это можно легко достичь.

Для iOS 6 и выше

 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; NSDictionary *parameters = @{@"foo": @"bar"}; NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"]; [manager POST:@"http://example.com/resources.json" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { [formData appendPartWithFileURL:filePath name:@"image" error:nil]; } success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"Success: %@", responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; 

Если проект лучше подходит для iOS 7 и выше.

 NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil]; } error:nil]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; NSProgress *progress = nil; NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { if (error) { NSLog(@"Error: %@", error); } else { NSLog(@"%@ %@", response, responseObject); } }]; [uploadTask resume]; 

над образцами кода из документации библиотеки. Что можно найти на странице https://github.com/AFNetworking/AFNetworking

Вы можете использовать мою библиотеку для такого сетевого запроса:

 WebRequest *request = [[WebRequest alloc] initWithPath:@"...documents/create.json"]; request.delegate = delegate; request.notificationName = @"NotificationDocumentUploaded"; 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"]; // optional [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 setValue:[NSString stringWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"]; [request setHTTPMethod:@"POST"]; [WebRequestProcessor process:request]; 

Делегат настроен для уведомления о ходе загрузки.

Interesting Posts

Как отменить все NSURLConnections в фоновом режиме в iOS

Как вставить тип даты в MongoDB с iOS Swift (через JSON и Node.js)

Как обрабатывать задержку около 0,15 секунды после использования метода задержки задержки UIGestureRecognizerTouchesBegan?

Изменение ориентации OpenGL заставляет iPad перезапускать

Время отображения индикатора активности Alert View

Где печатают заявления в опубликованном приложении iOS?

не может изменить текстовое значение UILabel внутри программно созданного пользовательского представления

Нажатие новых профилей предоставления

CABasicAnimation завершается при показе другого vc modally

RestKit RKRequests arent отправляется немедленно

Как удалить пространство, занятое кнопкой, нажав кнопку

Поиск нерегулярного представления, содержащего точку

Уведомления MPMoviePlayerViewController

Как сохранить или безопасно избегать ключевых социальных сетей, таких как Facebook или LinkedIn в GitHub

Выполнение команд терминала в MobileSafari

Давайте будем гением компьютера.