zoukankan      html  css  js  c++  java
  • iOS网络-NSURLSessionDataTask大文件离线断点下载

    什么叫离线断点下载,就是用户下载中关闭程序重新打开可以继续下载

    代码实现如下:

    #import "ViewController.h"
    @interface ViewController ()<NSURLSessionDataDelegate>
    //输出流
    @property (nonatomic, strong) NSOutputStream *stream ;
    //Task对象
    @property (nonatomic, strong) NSURLSessionDataTask *dataTask;
    //文件总大小
    @property (nonatomic, assign) NSInteger totalSize;
    //文件当前已下载大小
    @property (nonatomic, assign) NSInteger currentSize;
    //文件的全路径
    @property (nonatomic, strong) NSString *fullPath
    //会话对象
    @property (nonatomic, strong) NSURLSession *session;
    @end
    
    @implementation ViewController
    //懒加载会话对象
    -(NSURLSession *)session
    {
        if (_session == nil) {
            //3.创建会话对象
            /*
             第一个参数:配置信息
             第二个参数:代理  self
             第三个参数:代理方法的队列
             */
            NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
            _session = session;
        }
        return _session;
    }
    //懒加载task
    -(NSURLSessionDataTask *)dataTask
    {
        if (_dataTask == nil) {
    
            //1.确定请求路径
            NSString *urlStr = @"http://120.25.226.186:32812/resources/videos/minion_01.mp4";
            NSURL *url = [NSURL URLWithString:urlStr];
    
            //2.创建请求对象
            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
            NSString *fileName = [urlStr lastPathComponent];
            NSInteger curentSize = [self getCurrentLength:fileName];
                     //记录当前已下载的大小
            self.currentSize = curentSize;
            //设置请求头,表示下一次下载从哪个地方开始下载
            NSString *range = [NSString stringWithFormat:@"bytes=%zd-",curentSize];
            [request setValue:range forHTTPHeaderField:@"Range"];
    
            //4.创建task
            NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];
    
            _dataTask = dataTask;
    
        }
        return _dataTask;
    }
    
    -(void)dealloc
    {
        //释放session 俩种方法任选一种
        [self.session invalidateAndCancel];
    //    [self.session resetWithCompletionHandler:nil];
    }
    
    //开始下载
    - (IBAction)startBtnClick:(id)sender
    {
        [self.dataTask resume];
    }
    //暂停下载
    - (IBAction)suspendBtnClick:(id)sender
    {
        [self.dataTask suspend];
    }
    //继续下载
    - (IBAction)goOnBtnClick:(id)sender
    {
        [self.dataTask resume];
    }
    //得到当前下载进度
    -(NSInteger)getCurrentLength:(NSString *)fileName
    {
        self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:fileName];
    
        NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:self.fullPath error:nil];
        NSLog(@"%@",dict);
        //获取文件已下载大小
        NSInteger size = [dict[@"NSFileSize"] integerValue];
        return size;
    }
    #pragma mark - NSURLSessionDataDelegate
    //1.接收到服务器响应的时候
    -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
    {
        //expectedContentLength:本次请求的数据的大小
        self.totalSize = response.expectedContentLength + self.currentSize;
    
    
        //创建输出流
        NSOutputStream *stream = [[NSOutputStream alloc]initToFileAtPath:self.fullPath append:YES];
    
        //打开流
        [stream open];
        self.stream = stream;
    
        //通过该回调告诉系统是否要继续接收服务器返回给我们的数据NSURLSessionResponseAllow==接收
        completionHandler(NSURLSessionResponseAllow);
    }
    //2.接收到服务器返回数据的时候调用,会调用多次
    -(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
    {
        NSLog(@"didReceiveData---%zd",data.length);
    
        [self.stream write:data.bytes maxLength:data.length];
    
        self.currentSize +=data.length;
       //打印下载进度
        NSLog(@"%f",1.0 * self.currentSize / self.totalSize);
    }
    
    //3.请求结束的时候调用(成功|失败),如果失败那么error有值
    -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
    {
        NSLog(@"didCompleteWithError---%@",[NSThread currentThread]);
    
      //关闭流
        [self.stream close];
        self.stream = nil;
    }
    @end
  • 相关阅读:
    udp和tcp
    以查询代替临时变量
    memcached内存管理
    设计模式适配器模式
    排序算法
    防止表单重复提交
    php的引用
    按位与,按位异或,按位取反
    git常用操作
    http
  • 原文地址:https://www.cnblogs.com/liugengqun/p/5140141.html
Copyright © 2011-2022 走看看