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,主要用于处理下载请求,有很大的优势
      NSURLSession 的子类

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 设置代理发送请求

  1. 创建 NSURLSession 对象设置代理
  2. 使用 NSURLSession 对象创建 Task
  3. 执行 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];
  1. 遵守协议,实现代理方法(常用的有三种代理方法)
-(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
原创粉丝点击