2014-03-11 2 views
1

파일을 HTTP 서버에 업로드하고 싶습니다. 나는 그것을 지금 좋아한다 :iOS, multipartform-data로 파일 업로드

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"값으로 "user"를 제출했습니다. 나는 같은 배열의 어떤 종류를 보낼 싶습니다

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

나는이 사용하는 HTTP multipartform 데이터처럼 할 수있는 알고 있지만 난 정말 돈은 내가 어떻게 작동하는지 이해하지 어떻게 알고 있습니다. 어떤 사람이 저에게 어떻게 설명하고 어떻게 작동하는지 설명 할 수 있습니까? 이 같은

답변

4

시도 뭔가 :

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 헤더 필드를 추가하는 것을 잊지 말아.

+0

고마워요, 작동 lika 매력 :) – AYMADA

+0

우리는 단지 파일을 추가 매개 변수를 업로드하는 경우, Content-Length == data.length? – Zhang

1

당신은 네트워크 요청에 대한 내 library를 사용할 수 있습니다

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]; 

대리인은 업로드 진행에 대한 알림을 설정합니다.

3

AFNetowrking은 오늘의 핸디 솔루션입니다. 이것을 쉽게 달성 할 수 있습니다.

아이폰 OS 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); 
}]; 

프로젝트는 아이폰 OS 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

+0

요청하지 못함 : 허용되지 않는 content-type : AFNetworking을 사용하는 text/html –

관련 문제