iOS開發之網路編程--5、NSURLSessionUploadTask+NSURLSessionDataDelegate代理上傳,nsurlsessiondelegate
前言:關於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 NSURLSessionDataDelegate105 /*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)totalBytesExpectedToSend111 {112 NSLog(@"已經上傳了%f的資料",1.0 * totalBytesSent/totalBytesExpectedToSend );113 }114 @end