iOS开发之网络编程

时间:2022-12-14 22:58:05

前言:关于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