NSURLConnection實(shí)現(xiàn)文件上傳
- 文件上傳步驟
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ù))- 拼接文件參數(shù)
- 拼接非文件參數(shù)
- 添加結(jié)尾標(biāo)記
6.
使用NSURLConnection sendAsync發(fā)送異步請(qǐng)求上傳文件
7.
解析服務(wù)器返回的數(shù)據(jù)
- 文件上傳設(shè)置請(qǐng)求體的數(shù)據(jù)格式
//請(qǐng)求體拼接格式
//分隔符:----WebKitFormBoundaryhBDKBUWBHnAgvz9c
//01.文件參數(shù)拼接格式
--分隔符
Content-Disposition:參數(shù)
Content-Type:參數(shù)
空行
文件參數(shù)
//02.非文件拼接參數(shù)
--分隔符
Content-Disposition:參數(shù)
空行
非文件的二進(jìn)制數(shù)據(jù)
//03.結(jié)尾標(biāo)識(shí)
--分隔符--
- 文件上傳相關(guān)代碼
-(void)upload {
//1.確定請(qǐng)求路徑
NSURL *url = [NSURL URLWithString:@"URL字符串"];
//2.創(chuàng)建一個(gè)可變的請(qǐng)求對(duì)象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3.設(shè)置請(qǐng)求方式為POST
request.HTTPMethod = @"POST";
//4.設(shè)置請(qǐng)求頭
NSString *filed = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
[request setValue:filed forHTTPHeaderField:@"Content-Type"];
//5.設(shè)置請(qǐng)求體
NSMutableData *data = [NSMutableData data];
//5.1 文件參數(shù)
/*
--分隔符
Content-Disposition:參數(shù)
Content-Type:參數(shù)
空行
文件參數(shù)
*/
[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"test.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:KnewLine];
[data appendData:KnewLine];
UIImage *image = [UIImage imageNamed:@"test"];
NSData *imageData = UIImagePNGRepresentation(image);
[data appendData:imageData];
[data appendData:KnewLine];
//5.2 非文件參數(shù)
/*
--分隔符
Content-Disposition:參數(shù)
空行
非文件參數(shù)的二進(jìn)制數(shù)據(jù)
*/
[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:[@"Content-Disposition: form-data;name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:KnewLine];
[data appendData:KnewLine];
NSData *nameData = [@"wendingding" dataUsingEncoding:NSUTF8StringEncoding];
[data appendData:nameData];
[data appendData:KnewLine];
//5.3 結(jié)尾標(biāo)識(shí)
//--分隔符--
[data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
request.HTTPBody = data;
//6.發(fā)送請(qǐng)求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {
//7.解析服務(wù)器返回的數(shù)據(jù)
NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];
}
- 如何獲得文件的MIMEType類型
- 直接對(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 = @"文件所在路徑";
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 = @"文件所在路徑";
[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);
}];
}
- 通過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);
}
NSURLSession實(shí)現(xiàn)文件上傳
- 實(shí)現(xiàn)文件上傳的方法
/*
第一個(gè)參數(shù):請(qǐng)求對(duì)象
第二個(gè)參數(shù):請(qǐng)求體(要上傳的文件數(shù)據(jù))
block回調(diào):
NSData:響應(yīng)體
NSURLResponse:響應(yīng)頭
NSError:請(qǐng)求的錯(cuò)誤信息
*/
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error)
- 設(shè)置代理,在代理方法中監(jiān)聽文件上傳進(jìn)度
/*
調(diào)用該方法上傳文件數(shù)據(jù)
如果文件數(shù)據(jù)很大凡纳,那么該方法會(huì)被調(diào)用多次
參數(shù)說明:
totalBytesSent:已經(jīng)上傳的文件數(shù)據(jù)的大小
totalBytesExpectedToSend:文件的總大小
*/
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
NSLog(@"%.2f",1.0 * totalBytesSent/totalBytesExpectedToSend);
}
- 關(guān)于NSURLSessionConfiguration相關(guān)
- 作用:可以統(tǒng)一配置NSURLSession,如請(qǐng)求超時(shí)等
- 創(chuàng)建的方式和使用
//創(chuàng)建配置的三種方式
+(NSURLSessionConfiguration *)defaultSessionConfiguration;
+(NSURLSessionConfiguration *)ephemeralSessionConfiguration;
+(NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);
//統(tǒng)一配置NSURLSession
-(NSURLSession *)session
{
if (_session == nil) {
//創(chuàng)建NSURLSessionConfiguration
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
//設(shè)置請(qǐng)求超時(shí)為10秒鐘
config.timeoutIntervalForRequest = 10;
//在蜂窩網(wǎng)絡(luò)情況下是否繼續(xù)請(qǐng)求(上傳或下載)
config.allowsCellularAccess = NO;
_session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}