我想将文件上传到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多部分数据这样做,但我真的不知道如何,我不明白它是如何工作的。有人可以解释一下我该怎么做以及它是如何工作的?
答案 0 :(得分: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];
另外不要忘记添加内容长度N#39;您的请求中的http标头字段。
答案 1 :(得分:3)
AFNetowrking是今天的Handy解决方案。可以轻松实现这一目标。
适用于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
找到答案 2 :(得分: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];
代理人已设置有关上传进度的通知。