▶ 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