iOS核心筆記——網路編程-檔案上傳

來源:互聯網
上載者:User

標籤:環境   檔案上傳   handle   過程   main   upload   本地   new   filename   

1、檔案上傳:

?重要:當使用者想向伺服器傳送用戶端本地檔案時,此時,需要使用POST請求方式、NSURLSessionUploadTask檔案上傳任務將檔案傳遞至伺服器。

1-1、技術點:

?重要:①佈建要求頭資訊,告訴伺服器本次網路請求是在向伺服器傳送檔案;②拼接要上傳的檔案的資料,拼接過程中一定要嚴格按照檔案上傳格式進行,否則,檔案上傳將會失敗。

1-2、檔案上傳格式:1、佈建要求頭資訊:

?重要:佈建要求頭,告訴伺服器這是一次檔案上傳操作。

2、設定檔案參數:

?重要:佈建要求體,將檔案轉換為位元據之後拼接在請求體中;拼接過程中一定要嚴格按照格式進行拼接,否則,將上傳失敗;所示,所有空行、換行均以\r\n表示,中參數結束標記與\r\n之間的空格實際是不存在的,只是為了方便閱讀。

3、設定非檔案參數:

?重要:非檔案參數與檔案參數在設定Content-Disposition時存在區別,檔案參數:name使用file,表示這是一個檔案,且還需向伺服器傳遞filename(即:檔案上傳至伺服器之後的名稱);非檔案參數:只需設定name,並用參數所對應的Key表示該參數,然後將參數的值以位元據形式拼接在參數值的位置。

2、檔案上傳功能實現:

?重要:檔案上傳,需要傳遞的資料可能非常的大;所以,不能使用簡單的GET請求,需要使用POST請求完成。而且,檔案上傳需要佈建要求頭的Content-Type資訊,所以,需要使用可變的請求對象(即:NSMutableURLRequest),使用KVC方法設定該屬性,告訴伺服器這是一次檔案上傳操作。

2-1、建立上傳請求操作:
1.- (void)upload{
2. // 1. 建立URL
3. NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
4.
5. // 2. 建立可變請求對象
6. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
7.
8. // 3. 佈建要求方法為POST
9. request.HTTPMethod = @"POST";
10.
11. // 4. 佈建要求頭資訊, 告訴伺服器這是一個檔案上傳請求
12. // 就這個地方from錯誤, 應當是form; 就這一個錯誤害我花了1個多小時
13.// [request setValue:[NSString stringWithFormat:@"multipart/from-data; boundary=%@", kBoundary] forHTTPHeaderField:@"Content-Type"];
14. [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kBoundary] forHTTPHeaderField:@"Content-Type"];
15.
16. // 4. 擷取預設配置資訊
17. NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
18.
19. // 5. 建立會話對象
20. NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
21.
22. // 6. 使用會話對象建立上傳任務對象
23. [[session uploadTaskWithRequest:request fromData:[self bodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
24.
25. NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
26. }] resume];
27.}

?重要:1、檔案上傳通常使用的是NSURLSessionTask家族的NSURLSessionUploadTask成員,設定完要求方法和要求標頭資訊之後;使用會話對象建立檔案上傳會話任務,並調用resume方法開啟檔案上傳任務操作。

?重要:2、在使用NSURLSessionUploadTask進行檔案上傳時,也可以設定會話對象的代理;以便監聽檔案上傳操作的進度,代理需要遵守【NSURLSessionDataDelegate協議】。常見代理方法:

1.
2.#pragma mark NSURLSessionDataDelegate
3.
4.//bytesSent 本次上傳的檔案資料大小
5.//totalBytesSent 已經上傳的檔案資料的總大小
6.//totalBytesExpectedToSend 檔案的總大小
7.-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
8.{
9. NSLog(@"%f",1.0 * totalBytesSent / totalBytesExpectedToSend);
10.}
2-2、拼接檔案參數和非檔案參數:
1./**
2. * 拼接請求體資料, 經測試沒有錯誤
3. */
4.- (NSMutableData *)getData{
5. // MARK: - 檔案參數
6. // 1. 建立data
7. NSMutableData *fileData = [NSMutableData data];
8.
9. // 2. 拼接--分割線
10. NSString *str = [NSString stringWithFormat:@"--%@", kBoundary];
11. [fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
12.
13. [fileData appendData:newLine];
14.
15. // 4. 拼接Content-Disposition
16. str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"Snip20161128_2.png\""];
17. [fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
18.
19. [fileData appendData:newLine];
20.
21. // 5. 拼接Content-Type, 檔案的MIMEType格式: 大類型/小類型
22. str = [NSString stringWithFormat:@"Content-Type: image/png"];
23. [fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
24.
25. [fileData appendData:newLine];
26.
27. // 6. 拼接空行, 為確保在任何環境下都能夠正確換行, 所以使用: \r\n
28.
29. [fileData appendData:newLine];
30.
31. // 7. 拼接檔案資料
32. [fileData appendData:[NSData dataWithContentsOfFile:@"/Users/hehuafeng/Desktop/Snip20161128_2.png"]];
33.
34. // 8. 檔案資料末尾換行
35. [fileData appendData:newLine];
36.
37. // MARK: - 非檔案參數
38. // 1. 拼接分割線
39. str = [NSString stringWithFormat:@"--%@", kBoundary];
40. [fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
41.
42. [fileData appendData:newLine];
43.
44. // 2. 拼接Content-Disposition
45. str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"username\""];
46. [fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
47.
48. [fileData appendData:newLine];
49. [fileData appendData:newLine];
50.
51. // 4. 拼接參數值
52. str = [NSString stringWithFormat:@"hahaha"];
53. [fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
54.
55. [fileData appendData:newLine];
56.
57. // MARK: - 拼接參數結束標記
58. str = [NSString stringWithFormat:@"--%@--", kBoundary];
59. [fileData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
60.
61. // MARK: - 返回拼接完畢的資料
62. return fileData;
63.}

?重要:1、拼接檔案非檔案參數時,一定要嚴格按照格式進行拼接;否則,將無法上傳檔案。

?重要:2、檔案參數與非檔案參數拼接步驟:--分割線 -> 換行(\r\n) -> 檔案參數的:Content-Dispositio -> 換行(\r\n) -> 檔案參數的:Content-Type -> 換行(\r\n) -> 空一行(\r\n) -> 二進位形式檔案參數值 -> 換行(\r\n) -> --分割線 -> 換行(\r\n) -> 非檔案的:Content-Disposition -> 換行(\r\n) -> 空一行(\r\n) -> 二進位形式非檔案參數值 -> 換行(\r\n) -> --分割線--(即:結束標記)

2-3、檔案上傳使用的宏:
1.// 分割線, 為確保分析按正常換行; 所以, 使用\r\n
2.#define kBoundary @"----WebKitFormBoundarybH2OxPYq4hkfGHY6"
3.#define newLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]

iOS核心筆記——網路編程-檔案上傳

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.