前言:關於NSURLSession的主要內容快到尾聲了,這里就講講文件上傳。關於文件上傳當然就要使用NSURLSessionUploadTask,這里直接講解常用的會和代理NSURLSessionDataDelegate一起搭配實現文件上傳功能。另外,下面使用的文件上傳思路是和NSURLConnection中本人之前的隨筆《iOS開發之網絡編程--使用NSURLConnection實現文件上傳》提到的上傳思路是一樣的,都是要將請求信息拼接起來,然后傳入到請求里進行上傳。這個拼接過程是必要的,但是也是比較繁瑣的,下面我就不過多講解細節了。另外使用代理也比較簡單,所以就直接展示全部源碼。
1 #import "ViewController.h" 2 #define kBoundary @"----WebKitFormBoundary0IQAt0HA7oxwIx3f" 3 #define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding] 4 5 @interface ViewController ()<NSURLSessionDataDelegate> 6 7 @end 8 9 @implementation ViewController 10 11 -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event 12 { 13 NSLog(@"------"); 14 //1.創建會話對象,設置代理 15 NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]]; 16 17 //2.創建請求對象 18 NSURL *url =[NSURL URLWithString:@"http://120.25.226.186:32812/upload"]; 19 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 20 21 //2.1 修改請求方法 22 request.HTTPMethod = @"POST"; 23 24 //2.2 設置請求頭 25 NSString *header = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",kBoundary]; 26 [request setValue:header forHTTPHeaderField:@"Content-Type"]; 27 28 //3.創建上傳task 29 /* 30 第一個參數:請求對象 31 第二個參數:要上傳文件的參數(二進制數據 32 第三個參數:completionHandler 33 data:服務器返回的結果(響應體信息) 34 response:響應頭 35 */ 36 NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 37 38 //5.解析結果 39 NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]); 40 }]; 41 42 //4.執行任務 43 [uploadTask resume]; 44 45 } 46 47 -(NSData *)getBodyData 48 { 49 //5.拼接數據 50 NSMutableData *fileData = [NSMutableData data]; 51 52 //5.1 拼接文件參數 53 /* 54 --分隔符 55 Content-Disposition: form-data; name="file"; filename="Snip20151228_572.png" 56 Content-Type: image/png 57 空行 58 文件二進制數據 59 */ 60 [fileData appendData:[[NSString stringWithFormat:@"--%@",kBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 61 [fileData appendData:KNewLine]; 62 // name="file":參數,是固定的 63 // filename:文件上傳到服務器以什么名字來保存,隨便 64 [fileData appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"Snip20151228_572.png\"" dataUsingEncoding:NSUTF8StringEncoding]]; 65 66 [fileData appendData:KNewLine]; 67 //Content-Type:要上傳的文件的類型 (MIMEType) 68 [fileData appendData: [@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]]; 69 [fileData appendData:KNewLine]; 70 [fileData appendData:KNewLine]; 71 72 UIImage *image = [UIImage imageNamed:@"Snip20151229_713"]; 73 NSData *imageData = UIImagePNGRepresentation(image); 74 [fileData appendData:imageData]; 75 [fileData appendData:KNewLine]; 76 77 //5.2 拼接非文件參數 78 /* 79 --分隔符 80 Content-Disposition: form-data; name="username" 81 空行 82 非文件參數的二進制數據 83 */ 84 [fileData appendData:[[NSString stringWithFormat:@"--%@",kBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 85 [fileData appendData:KNewLine]; 86 87 //username:同file 是服務器規定 88 [fileData appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]]; 89 [fileData appendData:KNewLine]; 90 [fileData appendData:KNewLine]; 91 [fileData appendData:[@"dashen9" dataUsingEncoding:NSUTF8StringEncoding]]; 92 [fileData appendData:KNewLine]; 93 94 //5.3 拼接結尾標識 95 /* 96 --分隔符-- 97 */ 98 [fileData appendData:[[NSString stringWithFormat:@"--%@--",kBoundary] dataUsingEncoding:NSUTF8StringEncoding]]; 99 100 return fileData; 101 } 102 103 #pragma mark ---------------------- 104 #pragma mark NSURLSessionDataDelegate 105 /* 106 第一個參數:bytesSent本次發送數據的大小 107 第二個參數:totalBytesSent一共發送了多少數據 108 第三個參數:totalBytesExpectedToSend文件的總大小 109 */ 110 -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend 111 { 112 NSLog(@"已經上傳了%f的數據",1.0 * totalBytesSent/totalBytesExpectedToSend ); 113 } 114 @end
