▶ NSURLSession
NSURLSession 的使用非常简单,它先根据会话对象创建一个请求任务,然后执行该任务即可
NSURLSession 特点
A. NSURLSession 支持 http 2.0 协议
B. 处理下载任务的时候可以直接把数据下载到磁盘中
C. 支持后台下载和上传
D. 同一个 session 发送多次请求,只需要建立一次连接(复用了 TCP)
E. 提供了全局的 session 并且可以统一配置,使用更加方便
F. 下载的时候是多线程异步处理,效率更高
NSURLSessionTask 本身是一个抽象类,在使用时通常是根据具体的需求使用其子类
A. NSURLSessionDataTask: 可以用来发送常见的 Get/Post请求,既可以用来上传也可以用来下载
B. NSURLSessionDownloadTask:可以用来发送下载请求,专门用来下载数据
C. NSURLSessionUploadTask: 可以用来发送上传请求,专门用来上传数据
▶ Get 请求
使用 NSURLSession 发送 Get请求 和使用 NSURLConnection 发送 Get请求 相似,过程如下
A. 确定请求路径
B. 创建请求对象(注:这一步可以省略)
C. 创建会话对象
D. 创建请求任务
E. 执行 Task,数据处理
代码示例:下面实现一个 Get请求
1 #import "ViewController.h"
2 @implementation ViewController
3
4 - (void)viewDidLoad {
5
6 [super viewDidLoad];
7 [self makeGet1];// 方式一
8
9 }
10
11 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
12 [self makeGet2];// 方式二
13 }
14
15 // 方式一:根据请求对象发送请求
16 -(void)makeGet1{
17
18 NSURL *url = [NSURL URLWithString:@"http://apis.juhe.cn/vin/query?key=&vin=WP1AB2959GL065973"];
19 NSURLRequest *request = [NSURLRequest requestWithURL:url];
20 // 会话对象
21 NSURLSession *session = [NSURLSession sharedSession];
22
23 // 根据会话对象创建一个 Task
24 /*
25 第 1 个参数:请求对象
26 第 2 个参数:completionHandler 回调(请求完成后成功或失败)
27 data:响应体信息(期望数据)
28 response:响应头信息,主要是对服务器端的描述
29 error:错误信息。如果请求失败,则 error 有值
30 */
31 NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
32
33 if (error == nil) {
34
35 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
36 NSLog(@"%@",dict);
37 }else{
38 NSLog(@"%@",error);
39 }
40 }];
41
42 // 执行任务
43 [dataTask resume];
44 }
45
46 // 方式二:跳过请求对象,直接根据请求路径发送请求
47 -(void)makeGet2{
48
49 NSString *urlStr = @"http://api.map.baidu.com/place/v2/search?query=银行®ion=郑州&output=json&ak=6E823f587c95f0148c19993539b99295";
50 NSURL *url = [NSURL URLWithString:[urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
51 NSURLSession *session = [NSURLSession sharedSession];
52
53 // 该方法内部会自动将请求路径包装成一个请求对象,该请求对象默认包含了请求头信息和请求方法
54 // 如果要发送的是 Post请求,则不能使用该方法
55 NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
56
57 if (error == nil) {
58
59 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
60 NSLog(@"%@",dict);
61 }else{
62 NSLog(@"%@",error);
63 }
64 }];
65
66 // 执行任务
67 [dataTask resume];
68 }
69
70 @end
▶ Post 请求
使用 NSURLSession 发送 Post请求 同样和 NSURLConnection 相似!步骤如下
A. 确定请求路径
B. 创建可变请求对象:NSMutableURLRequest(该步骤不可省略)
C. 配置请求方法为 Post
D. 配置请求体(参数转换为二进制)
E. 会话对象:NSURLSession
F. 根据会话对象创建请求任务:NSURLSessionDataTask
G. 执行 Task,进行数据处理
代码示例:下面实现 POST请求
1 #import "ViewController.h"
2 @implementation ViewController
3
4 - (void)viewDidLoad {
5 [super viewDidLoad];
6 self.view.backgroundColor = [UIColor whiteColor];
7
8 // Post请求
9 NSURLSession *session = [NSURLSession sharedSession];
10 NSURL *url = [NSURL URLWithString:@"http://api.tudou.com/v3/gw"];
11 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
12 // 请求方法
13 request.HTTPMethod = @"POST";
14 // 请求体
15 request.HTTPBody = [@"method=user.item.get&appKey=43db911a75b88c11&format=json&user=ttr2008&pageNo=1&pageSize=10" dataUsingEncoding:NSUTF8StringEncoding];
16
17 // 根据会话对象创建 Task
18 NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
19
20 if (error == nil) {
21 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
22 NSLog(@"__:%@",dict);
23 }else{
24 NSLog(@"__:%@",error);
25 }
26 }];
27 // 开启 Task
28 [dataTask resume];
29 }
30
31 @end
▶ NSURLSession 代理方法
有时候我们需要监听网络请求的过程,比如下载文件需监听文件下载进度,那么就需要用到代理方法!具体实现如下
1 #import "ViewController.h"
2 @interface ViewController () <NSURLSessionDataDelegate>// 协议
3
4 @property (nonatomic,strong)NSMutableData *responseData;
5
6 @end
7
8 @implementation ViewController
9
10 - (void)viewDidLoad {
11 [super viewDidLoad];
12 self.view.backgroundColor = [UIColor whiteColor];
13
14 NSString *urlStr = @"http://api.map.baidu.com/place/v2/search?query=银行®ion=郑州&output=json&ak=6E823f587c95f0148c19993539b99295";
15 NSURL *url = [NSURL URLWithString:[urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
16 NSURLRequest *request = [NSURLRequest requestWithURL:url];
17
18 // 获得会话对象,并设置代理
19 // 第 1 个参数:会话对象的配置信息 defaultSessionConfiguration 表示默认配置
20 // 第 2 个参数:谁成为代理
21 // 第 3 个参数:队列,该队列决定代理方法在哪个线程中调用,可以传主队列/非主队列:
22 // [NSOperationQueue mainQueue] 主队列: 代理方法在主线程中调用
23 // [[NSOperationQueue alloc] init] 非主队列: 代理方法在子线程中调用
24
25 NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
26
27 NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
28 [dataTask resume];
29 }
30
31
32 #pragma mark - <NSURLSessionDataDelegate>
33 // 接收到服务器响应的时候调用该方法
34 -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
35
36 /*
37 NSURLSessionResponseCancel = 0 默认的处理方式,取消
38 NSURLSessionResponseAllow = 1 接收服务器返回的数据
39 NSURLSessionResponseBecomeDownload = 2 变成一个下载请求
40 NSURLSessionResponseBecomeStream 变成一个流
41 */
42
43 // 使用 completionHandler:告诉系统应该如何处理服务器返回的数据,默认是取消
44 completionHandler(NSURLSessionResponseAllow);
45 self.responseData = [NSMutableData data];
46 }
47
48 // 接收到服务器返回数据的时候会调用该方法,如果数据较大那么该方法可能会调用多次
49 -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
50
51 // 拼接服务器返回的数据
52 [self.responseData appendData:data];
53 }
54
55 // 当请求完成时候会调用该方法
56 -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
57
58 if(error == nil){
59 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:nil];
60 NSLog(@"%@:",dict);
61 }else{
62 NSLog(@"%@:",error);
63 }
64 }
65
66 @end