什么叫离线断点下载,就是用户下载中关闭程序重新打开可以继续下载
代码实现如下:
#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.创建taskNSURLSessionDataTask *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