NSURLSession

简介

  • 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值