一、文件數(shù)據(jù)拼接
-
文件上傳設(shè)置請(qǐng)求體的數(shù)據(jù)格式
//請(qǐng)求體拼接格式 //分隔符:----WebKitFormBoundaryhBDKBUWBHnAgvz9c //01.文件參數(shù)拼接格式 --分隔符 Content-Disposition:參數(shù) Content-Type:參數(shù) 空行 文件參數(shù) 文件參數(shù) --分割線\r\n Content-Disposition: form-data; name="參數(shù)名"; filename="文件名"\r\n Content-Type: 文件的MIMEType\r\n \r\n 文件數(shù)據(jù) \r\n 參數(shù)結(jié)束的標(biāo)記 --分割線--\r\n //02.非文件拼接參數(shù) --分隔符 Content-Disposition:參數(shù) 空行 非文件的二進(jìn)制數(shù)據(jù) 設(shè)置請(qǐng)求頭 [request setValue:@"multipart/form-data; boundary=分割線" forHTTPHeaderField:@"Content-Type"]; 設(shè)置請(qǐng)求體 非文件參數(shù) --分割線\r\n Content-Disposition: form-data; name="參數(shù)名"\r\n \r\n 參數(shù)值 \r\n //03.結(jié)尾標(biāo)識(shí) --分隔符--
相關(guān)代碼
-(NSData *)bodyData
{
NSMutableData *fileData = [NSMutableData data];
/*
5.1 拼接文件參數(shù):
--分隔符
Content-Disposition: form-data; name="file"; filename="123.png"
Content-Type: application/octet-stream
空行
文件參數(shù)
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
NSString *str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"123.png\""];
[fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
// application/octet-stream 通用的二進(jìn)制數(shù)據(jù)格式
[fileData appendData:[@"Content-Type: application/octet-stream" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine];
UIImage *image = [UIImage imageNamed:@"123"];
NSData *imageData = UIImagePNGRepresentation(image);
[fileData appendData:imageData];
[fileData appendData:KNewLine];
/*
5.2 拼接非文件參數(shù):
--分隔符
Content-Disposition: form-data; name="username"
空行
fzgq
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine];
[fileData appendData:[@"fzgq" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
/*
5.3 結(jié)尾標(biāo)識(shí)
--分隔符--
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
return fileData;
}
補(bǔ)充:如何獲得文件的MIMEType類型
(1)直接對(duì)該對(duì)象發(fā)送一個(gè)異步網(wǎng)絡(luò)請(qǐng)求泛源,在響應(yīng)頭中通過response.MIMEType拿到文件的MIMEType類型
//如果想要及時(shí)拿到該數(shù)據(jù)潭袱,那么可以發(fā)送一個(gè)同步請(qǐng)求
- (NSString *)getMIMEType
{
NSString *filePath = @"/Users/文頂頂/Desktop/備課/其它/swift.md";
NSURLResponse *response = nil;
[NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]] returningResponse:&response error:nil];
return response.MIMEType;
}
//對(duì)該文件發(fā)送一個(gè)異步請(qǐng)求,拿到文件的MIMEType
- (void)MIMEType
{
// NSString *file = @"file:///Users/文頂頂/Desktop/test.png";
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:@"/Users/文頂頂/Desktop/test.png"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {
// response.MIMEType
NSLog(@"%@",response.MIMEType);
}];
}
(2)通過UTTypeCopyPreferredTagWithClass方法
//注意:需要依賴于框架MobileCoreServices
- (NSString *)mimeTypeForFileAtPath:(NSString *)path
{
if (![[[NSFileManager alloc] init] fileExistsAtPath:path]) {
return nil;
}
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL);
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);
CFRelease(UTI);
if (!MIMEType) {
return @"application/octet-stream";
}
return (__bridge NSString *)(MIMEType);
//return NSMakeCollectable(MIMEType);
}
二甫匹、NSURLSession---Upload(文件上傳)
主要通過NSURLSessionUpLoadTask來上傳,其父類是NSURLSessionTask
文件上傳步驟
1)確定上傳路徑
2)創(chuàng)建可變的請(qǐng)求對(duì)象
3)修改請(qǐng)求方法切POST
4)設(shè)置請(qǐng)求頭信息(告訴服務(wù)器這是一個(gè)文件上傳請(qǐng)求)
5)按照固定的格式來拼接參數(shù)(文件參數(shù)&非文件參數(shù)&結(jié)尾標(biāo)識(shí))
6)創(chuàng)建會(huì)話對(duì)象(session)
7)根據(jù)會(huì)話對(duì)象創(chuàng)建uploadTask(文件上傳任務(wù))
8)執(zhí)行uploadTask
9)解析服務(wù)器返回的數(shù)據(jù)
說明:
1)設(shè)置請(qǐng)求頭信息的格式:Content-Type:multipart/form-data; boundary=分隔符
2)拼接參數(shù)的固定格式
--分隔符
Content-Disposition: form-data; name="file"; filename="Snip20160407_10.png"
Content-Type: image/png
空行
文件參數(shù)
--分隔符
Content-Disposition: form-data; name="username"
空行
非文件參數(shù)
—分隔符--
3)可以設(shè)置代理,在代理方法中監(jiān)聽文件上傳的進(jìn)度块攒。
//上傳文件-delegate
-(void)uploadDelegate
{
//1.創(chuàng)建session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//2.創(chuàng)建可變的請(qǐng)求對(duì)象
NSURL *url =[NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3.修改請(qǐng)求方法為POST
request.HTTPMethod = @"POST";
//4.設(shè)置請(qǐng)求頭信息,告訴服務(wù)器這是一個(gè)上傳請(qǐng)求
NSString *value =[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
[request setValue:value forHTTPHeaderField:@"Content-Type"];
//5.拼接文件和非文件參數(shù)
NSData *dataM = [self bodyData];
//6.根據(jù)session創(chuàng)建uploadTask
/*
//PUT
// [session uploadTaskWithRequest:<#(nonnull NSURLRequest *)#> fromFile:<#(nonnull NSURL *)#>]
*/
/*
第一個(gè)參數(shù):請(qǐng)求對(duì)象(可變)
第二個(gè)參數(shù):要上傳的文件參數(shù):按照固定的格式拼接
第三個(gè)參數(shù):completionHandler
當(dāng)上傳完成之后調(diào)用
data:服務(wù)器返回給我們的響應(yīng)體信息
response:響應(yīng)頭
error:請(qǐng)求失敗,error有值
*/
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:dataM completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//8.解析數(shù)據(jù)
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];
//7.啟動(dòng)任務(wù)
[uploadTask resume];
}
/*
上傳文件的時(shí)候調(diào)用:會(huì)被調(diào)用多次
bytesSent:本次上傳的文件的大小
totalBytesSent:已經(jīng)上傳的文件的大小
totalBytesExpectedToSend:文件的總大小
*/
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
NSLog(@"%f",1.0* totalBytesSent/totalBytesExpectedToSend);
}
//上傳文件-block
-(void)upload
{
//1.創(chuàng)建session
NSURLSession *session = [NSURLSession sharedSession];
//2.創(chuàng)建可變的請(qǐng)求對(duì)象
NSURL *url =[NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3.修改請(qǐng)求方法為POST
request.HTTPMethod = @"POST";
//4.設(shè)置請(qǐng)求頭信息,告訴服務(wù)器這是一個(gè)上傳請(qǐng)求
NSString *value =[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
[request setValue:value forHTTPHeaderField:@"Content-Type"];
//5.拼接文件和非文件參數(shù)
NSData *dataM = [self bodyData];
//6.根據(jù)session創(chuàng)建uploadTask
/*
//PUT
// [session uploadTaskWithRequest:<#(nonnull NSURLRequest *)#> fromFile:<#(nonnull NSURL *)#>]
*/
/*
第一個(gè)參數(shù):請(qǐng)求對(duì)象(可變)
第二個(gè)參數(shù):要上傳的文件參數(shù):按照固定的格式拼接
第三個(gè)參數(shù):completionHandler
當(dāng)上傳完成之后調(diào)用
data:服務(wù)器返回給我們的響應(yīng)體信息
response:響應(yīng)頭
error:請(qǐng)求失敗,error有值
*/
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:dataM completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//8.解析數(shù)據(jù)
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];
//7.啟動(dòng)任務(wù)
[uploadTask resume];
}
-(NSData *)bodyData
{
NSMutableData *fileData = [NSMutableData data];
/*
5.1 拼接文件參數(shù):
--分隔符
Content-Disposition: form-data; name="file"; filename="123.png"
Content-Type: application/octet-stream
空行
文件參數(shù)
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
NSString *str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"123.png\""];
[fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
// application/octet-stream 通用的二進(jìn)制數(shù)據(jù)格式
[fileData appendData:[@"Content-Type: application/octet-stream" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine];
UIImage *image = [UIImage imageNamed:@"123"];
NSData *imageData = UIImagePNGRepresentation(image);
[fileData appendData:imageData];
[fileData appendData:KNewLine];
/*
5.2 拼接非文件參數(shù):
--分隔符
Content-Disposition: form-data; name="username"
空行
fzgq
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine];
[fileData appendData:[@"fzgq" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
/*
5.3 結(jié)尾標(biāo)識(shí)
--分隔符--
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
return fileData;
}
### NSURLConnection---UpLoad(NSURLConnection文件上傳)
- 文件上傳步驟
(1)確定請(qǐng)求路徑
(2)根據(jù)URL創(chuàng)建一個(gè)可變的請(qǐng)求對(duì)象
(3)設(shè)置請(qǐng)求對(duì)象,修改請(qǐng)求方式為POST
(4)設(shè)置請(qǐng)求頭佃乘,告訴服務(wù)器我們將要上傳文件(Content-Type)
(5)設(shè)置請(qǐng)求體(在請(qǐng)求體中按照既定的格式拼接要上傳的文件參數(shù)和非文件參數(shù)等數(shù)據(jù))
001 拼接文件參數(shù)
002 拼接非文件參數(shù)
003 添加結(jié)尾標(biāo)記
(6)使用NSURLConnection sendAsync發(fā)送異步請(qǐng)求上傳文件
(7)解析服務(wù)器返回的數(shù)據(jù)
文件上傳相關(guān)代碼
/*
上傳文件步驟:
1.設(shè)置請(qǐng)求頭
Content-Type:multipart/form-data; boundary=----WebKitFormBoundarygSvklWjpcBBprQ0A
2.設(shè)置請(qǐng)求體
按照固定的格式來拼接
------WebKitFormBoundarygSvklWjpcBBprQ0A
Content-Disposition: form-data; name="file"; filename=""
Content-Type: application/octet-stream
文件參數(shù)
------WebKitFormBoundarygSvklWjpcBBprQ0A
Content-Disposition: form-data; name="username"
fzgq
------WebKitFormBoundarygSvklWjpcBBprQ0A--
簡(jiǎn)化拼接格式:
分隔符:----WebKitFormBoundarygSvklWjpcBBprQ0A
1.拼接文件參數(shù):
--分隔符
Content-Disposition: form-data; name="file"; filename="123.png"
Content-Type: application/octet-stream
空行
文件參數(shù)
2.拼接非文件參數(shù):
--分隔符
Content-Disposition: form-data; name="username"
空行
fzgq
3.結(jié)尾標(biāo)識(shí)
--分隔符--
*/
#import "ViewController.h"
#define Kboundary @"----WebKitFormBoundarygSvklWjpcBBprQ0A"
#define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]
-(void)upload
{
//1.確定url
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
//2.創(chuàng)建可變的請(qǐng)求對(duì)象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3.修改請(qǐng)求方法為POST
request.HTTPMethod = @"POST";
//4.設(shè)置請(qǐng)求頭信息
/*Content-Type:multipart/form-data; boundary=----WebKitFormBoundarygSvklWjpcBBprQ0A*/
NSString *value =[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
[request setValue:value forHTTPHeaderField:@"Content-Type"];
//5.設(shè)置請(qǐng)求體
NSMutableData *fileData = [NSMutableData data];
/*
5.1 拼接文件參數(shù):
--分隔符
Content-Disposition: form-data; name="file"; filename="123.png"
Content-Type: application/octet-stream
空行
文件參數(shù)
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
NSString *str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"123.png\""];
[fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
// application/octet-stream 通用的二進(jìn)制數(shù)據(jù)格式
[fileData appendData:[@"Content-Type: application/octet-stream" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine];
UIImage *image = [UIImage imageNamed:@"123"];
NSData *imageData = UIImagePNGRepresentation(image);
[fileData appendData:imageData];
[fileData appendData:KNewLine];
/*
5.2 拼接非文件參數(shù):
--分隔符
Content-Disposition: form-data; name="username"
空行
fzgq
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine];
[fileData appendData:[@"fzgq" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
/*
5.3 結(jié)尾標(biāo)識(shí)
--分隔符--
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
//5.4 設(shè)置請(qǐng)求體參數(shù)
request.HTTPBody = fileData;
//6.發(fā)送請(qǐng)求s
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//7.解析返回的數(shù)據(jù)
NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];
}