一.为什么要使用NSURLSession来替换NSURLConnection
1.在iOS9.0之后,以前使用的NSURLConnection过期,苹果推荐使用NSURLSession来替换NSURLConnection完成网路请求相关操作。
2.NSURLSession的优势:
NSURLSession支持http2.0协议
处理下载任务的时候可以直接把数据下载到磁盘中
支持后台下载和上传
同一个session发送多次请求,只需要建立一次连接(复用了TCP)
提供了全局的session并且可以统一配置,使用更加方便
下载的时候是多线程异步处理,效率更高
3.NSURLSession的使用非常简单,先根据会话对象创建一个请求Task,然后执行该Task即可
4.NSURLSessionTask及其子类
NSURLSessionTask本身是一个抽象类,在使用的时候,通常是根据具体的需求使用它的几个子类
NSURLSessionDataTask可以用来发送常见的Get,Post请求,既可以用来上传也可以用来下载
NSURLSessionDownloadTask可以用来发送下载请求,专门用来下载数据
NSURLSessionUploadTask可以用来发送上传请求,专门用来上传数据
使用步骤:
创建Task,执行Task
二、使用NSURLSession发送GET请求
-(void)get
{
NSURL *url = [NSURL URLWithString:@"http://120"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//单例对象
NSURLSession *session = [NSURLSession sharedSession];
//创建task
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *_Nullable data, NSURLResponse * _Nullable response, NSError *_Nullable error){
}];
//执行task
[dataTask resume];
}
-(void)get2{
NSURL *url = [NSURL URLWithString:@"http://120"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//单例对象
NSURLSession *session = [NSURLSession sharedSession];
//创建task 这样传会自动将请求路径作为参数创建一个请求对象(GET),一定是GET请求
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *_Nullable data, NSURLResponse * _Nullable response, NSError *_Nullable error){
}];
//执行task
[dataTask resume];
}
三、发送POST请求
-(void)post
{
NSURL *url = [NSURL URLWithString:@"http://120"];
NSMUtableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=wly&password=520",dataUsingEncoding:NSUTF8StringEncoding];
//单例对象
NSURLSession *session = [NSURLSession sharedSession];
//创建task
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *_Nullable data, NSURLResponse * _Nullable response, NSError *_Nullable error){
//这里的代码是在子线程调用的,如果要更新UI的话需要做一个线程间通信
}];
//执行task
[dataTask resume];
}
NSURLSession相关代理
//获得会话对象配置信息
NSURLSessionConfiguration *config = [NSURLSessionConfiguration
defaultSessionConfiguration];
//设置代理
/*
第一个参数:会话对象的配置信息defaultSessionConfiguration 表示默认配置
第二个参数:谁成为代理,此处为控制器本身即self
第三个参数:队列,该队列决定代理方法在哪个线程中调用,可以传主队列|非主队列
[NSOperationQueue mainQueue] 主队列: 代理方法在主线程中调用
[[NSOperationQueue alloc]init] 非主队列: 代理方法在子线程中调用
*/
NSURLSession *session = [NSURLSession sessionWithConfiguration:config
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];
代理方法
//1.接收到服务器响应的时候调用该方法
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
//如果需要知道这个HTTP的所有信息,就需要获得NSURLResponse的子类
NSHTTPURLResponse *htttpResponse = (NSHTTPURLResponse *)response;
//打印信息
NSLog(@"响应头信息:%@",htttpResponse.allHeaderFields);
//定义一个容器用于接受服务器返回的数据
self.mData = [NSMutableData data];
//注意:和NSURLConnection不同点在于接收到响应信息之后,需要使用completionHandler回调告诉系统应该如何处理服务器返回的数据
//默认是取消的(NSURLSessionResponseCancel),下载(NSURLSessionResponseBecomeDownload),继续传递数据(NSURLSessionResponseAllow),只有设置这个值之后才会继续执行其它代理方法
completionHandler(NSURLSessionResponseAllow);
}
//2.接收到服务器返回数据的时候会调用该方法,如果数据较大那么该方法可能会调用多次
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
//拼接服务器返回的数据
[_mData appendData:data];
}
//3.当请求完成(成功|失败)的时候会调用该方法,如果请求失败,则error有值
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
//解析服务器返回的数据
//说明:(此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理)
NSLog(@"代理方法返回的响应信息:%@",[NSJSONSerialization JSONObjectWithData:_mData options:kNilOptions error:nil]);
}
NSURLSessionDownloadTask大文件下载
NSURL *url = [NSURL URLWithString:@"http://120"];
NSMUtableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//单例对象
NSURLSession *session = [NSURLSession sharedSession];
//创建task,该方法内部已经实现了边接收数据边写入沙盒(tmp)的操作,写入到临时文件目录
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL *_Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error){
//在子线程中处理该处代码
fullpath = [[NSSearchPathForDirectioriesIndomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
//文件剪切
[[NSFilemanager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullpath] error:nil]
}];
//执行task
[downloadTask resume];