iOS網(wǎng)絡(luò)編程--文件上傳

NSURLConnection實(shí)現(xiàn)文件上傳

  1. 文件上傳步驟
    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ù)

  1. 文件上傳設(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í) 
--分隔符--
  1. 文件上傳相關(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]);
 }];
 }
  1. 如何獲得文件的MIMEType類型
  2. 直接對(duì)該對(duì)象發(fā)送一個(gè)異步網(wǎng)絡(luò)請(qǐng)求,在響應(yīng)頭中通過(guò)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);
 }];
}
  1. 通過(guò)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)文件上傳

  1. 實(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)
  1. 設(shè)置代理,在代理方法中監(jiān)聽(tīng)文件上傳進(jìn)度
/*
調(diào)用該方法上傳文件數(shù)據(jù)
如果文件數(shù)據(jù)很大,那么該方法會(huì)被調(diào)用多次
參數(shù)說(shuō)明:
    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);
}
  1. 關(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;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容