一、基本简介
1. NSURLSessionDataTask 是 NSURLSessionTask 的子类,是一个具体的 网络请求(task) 类,是网络请求中最常用的请求之一
通常,NSURLSessionDataTask 用来请求数据,可以用来下载数据资源,例如 JSON 数据,图片数据等
2. 通常有以下几种方法创建一个 data task
1)方法一 : 使用 NSURLSession 的实例方法
1 // @param url 待请求的 URL 地址 2 // @param completionHandler 回调方法 3 // @param data 从服务器请求到的数据 4 // @param response 响应头信息 5 // @param error 错误信息 6 - (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
注意 :
该方法中会自动将 url 转换为一个请求对象(NSURLRequest),并且该请求对象是 GET 请求方式
回调方法是在子线程中运行的,所以如果在回调方法中刷新 UI 必须回到主线程中
回调方法中有两个参数 response / error,这两个参数和 该消息的接受者(即 NSURLSessionDataTask 对象)中的 response / error 是指同一个内容,即地址相同
使用该方法的缺点是不能监听获取数据的进度,因为只有当全部请求完数据后,才会调用这个方法,也就是说,data 中的数据是请求的全部数据
2)方法二 : 使用 NSURLSession 的实例方法
// @param request 请求对象 - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
方法二与方法一不同的地方在于 : 方法二可以手动设置请求对象,这样一来,就可以指定请求方式 GET/POST 中的一个;而方法一只能是 GET 请求方式
剩余的全部一样
3)方法三 : 代理
方法一和方法二唯一的缺点就是不能监控请求进度,因为只有当请求完全部的数据后才会调用回调方法,如果想要监控请求进度,必须使用代理的方法
使用代理首先要自定义 NSURLSession 对象,使用下面的方法可以设置代理对象
// @param configuration 配置信息对象 // @param delegate 代理对象 // @param queue 代理方法在哪个线程中运行,如果传 nil 则会在子线程中运行代理方法 + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id)delegate delegateQueue:(nullable NSOperationQueue *)queue;
同时,必须遵守相关的协议
再使用下面的方法创建 data task,因为此时下载的过程由代理方法执行,所以不能用 方法一/方法二 创建 data task 对象
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;
这两个方法的区别和方法一/方法二一样,使用第一个方法其内部会自动将其转换为一个 请求对象,并且是 GET 请求方式;使用方法二可以执行请求方式
二、示例代码
因为我是把所有的代码写到一个 demo 里的,所以有些目前不需要的东西可以不必理会
1)GET/POST 请求
首先在 main.storyboard 中拖入一个 UINavigationController ,并设置 static cell,如图
然后拖入一个 UIViewController 并选中第一个 cell,即 NSURLSessionDataTask,将 cell 和 UIViewController 连线,选择 push
在这个 UIViewController 中拖入一系列控件,如图
右上角的 UIBarButtonItem 是跳转到下一个界面的,不用管它
UIViewController 中的代码如下
1 #import "LHDataTaskViewController.h" 2 3 // GET 请求的 URL 4 static NSString * imageURL = @"http://120.25.226.186:32812/resources/images/minion_01.png"; 5 6 // POST 请求的 URL 7 static NSString * dataURL = @"http://api.hudong.com/iphonexml.do"; 8 9 @interface LHDataTaskViewController () 10 11 #pragma mark - 属性