NSURLSession
来源:互联网 发布:记事本软件无弹窗下载 编辑:程序博客网 时间:2024/06/03 17:57
简介
- NSURLConnection在iOS9被宣布弃用,NSURLSession从13年发展到现在,终于迎来了它独步江湖的时代.NSURLSession是苹果在iOS7后为HTTP数据传输提供的一系列接口,比NSURLConnection强大,坑少,好用
默认是挂起的,执行要resume
NSURLSession 的优势
- NSURLSession 支持 http2.0 协议
- 在处理下载任务的时候可以直接把数据下载到磁盘
- 支持后台下载|上传
- 同一个 session 发送多个请求,只需要建立一次连接(复用了TCP)
- 提供了全局的 session 并且可以统一配置,使用更加方便
- 下载的时候是多线程异步处理,效率更高
- 内存消耗很低
NSURLSessionTask 的子类
- NSURLSessionTask 是一个抽象类,如果要使用那么只能使用它的子类
- NSURLSessionTask 有两个子类
- NSURLSessionDataTask,可以用来处理一般的网络请求,如 GET | POST 请求等
- NSURLSessionDataTask 有一个子类为 NSURLSessionUploadTask,用于处理上传请求的时候有优势
- NSURLSessionDownloadTask,主要用于处理下载请求,有很大的优势
- NSURLSessionDataTask,可以用来处理一般的网络请求,如 GET | POST 请求等
GET请求
//1.url NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/demo.json"]; //2.NSURLSession NSURLSession *session = [NSURLSession sharedSession]; //3.获取task // 根据对象创建 Task 请求//// url 方法内部会自动将 URL 包装成一个请求对象(默认是 GET 请求)// completionHandler 完成之后的回调(成功或失败)//// param data 返回的数据(响应体)// param response 响应头// param error 错误信息 NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { //反序列化 id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSLog(@"%@",result); }]; //4.启动任务 [task resume];
POST请求
//1.url NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/demo.json"]; //2.创建可变请求对象 NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url]; //2.1修改请求方法 requestM.HTTPMethod = @"POST"; //2.2设置请求体 requestM.HTTPBody = [@"username=520&pwd=520&type=JSON" dataUsingEncoding:NSUTF8StringEncoding]; //创建会话对象 NSURLSession *session = [NSURLSession sharedSession];// 是全局的单例。整个系统。不建议用这个 //3.创建请求 Task NSURLSessionTask *task = [session dataTaskWithRequest:requestM completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSLog(@"%@",result); }]; //4.启动任何 [task resume];
NSURLSessionDataTask 设置代理发送请求
- 创建 NSURLSession 对象设置代理
- 使用 NSURLSession 对象创建 Task
- 执行 Task
//确定请求路径 NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"]; //创建可变请求对象 NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url]; //设置请求方法 requestM.HTTPMethod = @"POST"; //设置请求体 requestM.HTTPBody = [@"username=520&pwd=520&type=JSON" dataUsingEncoding:NSUTF8StringEncoding]; //创建会话对象,设置代理 /** 第一个参数:配置信息 第二个参数:设置代理 第三个参数:队列,如果该参数传递nil 那么默认在子线程中执行 */ NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil]; //创建请求 Task NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:requestM]; //发送请求 [dataTask resume];
- 遵守协议,实现代理方法(常用的有三种代理方法)
-(void)URLSession:(NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler { //子线程中执行 NSLog(@"接收到服务器响应的时候调用 -- %@", [NSThread currentThread]); self.dataM = [NSMutableData data]; //默认情况下不接收数据 //必须告诉系统是否接收服务器返回的数据 completionHandler(NSURLSessionResponseAllow);}-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { NSLog(@"接受到服务器返回数据的时候调用,可能被调用多次"); //拼接服务器返回的数据 [self.dataM appendData:data];}-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { NSLog(@"请求完成或者是失败的时候调用"); //解析服务器返回数据 NSLog(@"%@", [[NSString alloc] initWithData:self.dataM encoding:NSUTF8StringEncoding]);}
设置代理之后的强引用问题
- NSURLSession 对象在使用的时候,如果设置了代理,那么 session 会对代理对象保持一个强引用,在合适的时候应该主动进行释放
- 可以在控制器调用 viewDidDisappear 方法的时候来进行处理,可以通过调用 invalidateAndCancel 方法或者是
finishTasksAndInvalidate 方法来释放对代理对象的强引用- invalidateAndCancel 方法直接取消请求然后释放代理对象
- finishTasksAndInvalidate 方法等请求完成之后释放代理对象。
[self.session finishTasksAndInvalidate];
self.session = nil;
文件下载
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/sszip.zip"]; /* 如果在回调方法中,不做任何处理,下载的文件会被删除 下载文化是默认下载到tmp文件夹,系统会自动回收这个区域 设计目的: 1.通常从网络下载文件,什么样的格式文件最多?zip 2.如果是zip包,下载之后要解压 3.解压之后,原始的zip就不需要了。系统会自动帮你删除 */ [[[NSURLSession sharedSession]downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSLog(@"%@",location); //文件解压目标路径,不能指定目标文件。因为我们解压文件会产生多个文件 NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]; [SSZipArchive unzipFileAtPath:location.path toDestination:cachePath]; //工具类路径http://download.csdn.net/download/liyanjun201/10127149 }]resume];
设置下载进度和断电续传
@interface ViewController ()<NSURLSessionDownloadDelegate>//全局的网络会话,管理所有的网络任务@property(nonatomic,strong)NSURLSession *session;@property (weak, nonatomic) IBOutlet CCProgressBtn *progressView;@property(nonatomic,strong)NSURLSessionDownloadTask *downloadTask;@property(nonatomic,strong)NSData *resumeData;@end@implementation ViewController-(NSURLSession *)session{ if (_session == nil) { NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil]; } return _session;}-(void)dealloc{ NSLog(@"走了!");}//静态库:每一个应用程序都会需要一个副本//动态库,在系统中只有1个副本,只有苹果公司能够建立动态库,开发者建立的动态库是不允许上架- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.}-(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [self.session invalidateAndCancel]; self.session = nil;}- (IBAction)start:(id)sender { NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/abc.wmv"]; self.downloadTask = [self.session downloadTaskWithURL:url]; [self.downloadTask resume];}- (IBAction)pause:(id)sender { NSLog(@"暂停!"); [self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) { NSLog(@"数据的长度是:%tu",resumeData.length); self.resumeData = resumeData; //释放任务 self.downloadTask = nil; }];}- (IBAction)resumeClick:(id)sender { if (_resumeData == nil) { return; } self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData]; self.resumeData = nil; [self.downloadTask resume];}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/abc.wmv"]; //如果你要监听下载进度,必须使用代理。 //[NSURLSession sharedSession] 是全局的单例。整个系统å //如果你要更进下载进度,就不能block 。 [[self.session downloadTaskWithURL:url]resume];}#pragma mark --NSURLSessionDelegate//下载完成-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ NSLog(@"下载完成!"); [self.session finishTasksAndInvalidate]; self.session = nil;}//2下载进度/* session : downloadTask :调用代理方式的下载任何 bytesWritten:本次下载的字节数 totalBytesWritten:已经下载的字节数 totalBytesExpectedToWrite:期望下载的字节数————文件总大小 */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ float progress = (float)totalBytesWritten /totalBytesExpectedToWrite; NSLog(@"%f",progress); NSLog(@"%@",[NSThread currentThread]); dispatch_async(dispatch_get_main_queue(), ^{ self.progressView.progress = progress; });}//3.下载续传数据- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{}@end
阅读全文
0 0
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- NSURLSession
- 网络编程:TCP
- python基础总结
- redis下配置认证密码
- 安卓底部导航
- docker容器管理
- NSURLSession
- sftp下载文件并监控文件新增内容并按照指定速率把新内容追加到已下载内容后面
- 如何限制C++类的对象只能建立在堆上或栈上
- leetcode-167. Two Sum II
- 解决window.location.href不跳转,无反应,不执行的问题
- angular查询删除
- Android IOS WebRTC 音视频开发总结(六九)
- Spring Boot入门示例
- android 与JS之间的交互