依靠NSOutputStream,NSURLSession,NSURLSessionDataTask创建一个支持断点下载的任务

来源:互联网 发布:painter mac 2017 破解 编辑:程序博客网 时间:2024/06/02 00:16


////  ViewController.m//  BreakPointDownload////  Created by hq on 16/4/18.//  Copyright © 2016年 hanqing. All rights reserved.//#import "ViewController.h"#import "NSString+Hash.h"//定义文件等下载路径cache路径#define HQFilePath NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject#define HQFileURLString @"http://xxx/resources/videos/minion_01.mp4"//定义我们的文件名,直接只用url因为每个url对应一个文件是唯一的#define HQFileName HQFileURLString.md5String@interface ViewController () <NSURLSessionDataDelegate>@property (weak, nonatomic) IBOutlet UILabel *downloadStatus;@property (weak, nonatomic) IBOutlet UIProgressView *pro;@property (weak, nonatomic) IBOutlet UILabel *downSize;@property (weak, nonatomic) IBOutlet UIButton *loadBut;//文件等总大小@property(nonatomic,assign) NSInteger fileTotalSize;//当前文件下载了多少@property(nonatomic,assign) NSInteger fileCurrentSize;@property(nonatomic,strong) NSOutputStream *outputStream;@property(nonatomic,strong) NSURLSessionDataTask *task;- (IBAction)butClicked:(UIButton *)sender;@property(nonatomic,strong) NSOperationQueue *queue;@end@implementation ViewController-(NSURLSessionDataTask *)task{        if (!_task) {              NSURLSession *session=[NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];                NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:HQFileURLString]];                //指定从哪个位置继续下载        [request setValue:[NSString stringWithFormat:@"bytes=%ld-",[self getCurrentDownloadSize]] forHTTPHeaderField:@"Range"];                _task=[session dataTaskWithRequest:request];            }        return _task;}-(NSOutputStream *)outputStream{        if (!_outputStream) {               _outputStream=[[NSOutputStream alloc]initToFileAtPath:[HQFilePath stringByAppendingPathComponent:HQFileName] append:YES];    }    return _outputStream;}- (void)viewDidLoad {    [super viewDidLoad];        NSString *plistPath=[HQFilePath stringByAppendingPathComponent:@"fileSize.plist"];        //获取文件的总大小    NSInteger totalSize=[[NSDictionary dictionaryWithContentsOfFile:plistPath][HQFileName] integerValue];        if (totalSize==0) {        self.downSize.hidden=YES;        self.pro.progress=0;    }    else{        self.downSize.hidden=NO;        self.downSize.text=[NSString stringWithFormat:@"%.0f%",1.0*[self getCurrentDownloadSize]/totalSize*100];        self.pro.progress=1.0*[self getCurrentDownloadSize]/totalSize;    }        if (totalSize==[self getCurrentDownloadSize]&&totalSize!=0) {                self.downloadStatus.hidden=NO;                self.loadBut.enabled=NO;                [self.loadBut setTitle:@"开始下载" forState:UIControlStateNormal];            }        NSLog(@"%@",[HQFilePath stringByAppendingPathComponent:HQFileName]);    }- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    }- (IBAction)butClicked:(UIButton *)sender {        if ([self.loadBut.titleLabel.text isEqualToString:@"开始下载"]) {               [self.task resume];                [self.loadBut setTitle:@"暂停" forState:UIControlStateNormal];            }    else if([self.loadBut.titleLabel.text isEqualToString:@"暂停"]){                [self.task suspend];                [self.loadBut setTitle:@"继续下载" forState:UIControlStateNormal];            }    else{               [self.task resume];       [self.loadBut setTitle:@"暂停" forState:UIControlStateNormal];            }    }-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{        [self.outputStream open];        //必须开启才能接收服务端的请求    completionHandler(NSURLSessionResponseAllow);        //表示服务器当前能返回给我们的文件等大小    self.fileTotalSize=[response.allHeaderFields[@"Content-Length"] integerValue]+[self getCurrentDownloadSize];    //把文件的总大小写入我们的plist文件,key就用我们的文件名    NSString *plistPath=[HQFilePath stringByAppendingPathComponent:@"fileSize.plist"];        NSMutableDictionary *dict=[NSMutableDictionary dictionaryWithContentsOfFile:plistPath];    if (dict==nil) {        dict=[NSMutableDictionary dictionary];    }    //用我们的md5的url当作key    dict[HQFileName]=@(self.fileTotalSize);        [dict writeToFile:plistPath atomically:YES];        }-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{            [self.outputStream write:[data bytes] maxLength:data.length];        self.fileCurrentSize=[self getCurrentDownloadSize];        [[NSOperationQueue mainQueue] addOperationWithBlock:^{                self.downSize.hidden=NO;                self.pro.progress=(1.0*self.fileCurrentSize/self.fileTotalSize);                self.downSize.text=[NSString stringWithFormat:@"%.0f%%",(1.0*self.fileCurrentSize/self.fileTotalSize)*100];            }];    NSLog(@"%ld",self.fileCurrentSize);    }-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{        if (error) {        return;    }            [[NSOperationQueue mainQueue] addOperationWithBlock:^{            self.downloadStatus.hidden=NO;                self.loadBut.enabled=NO;                [self.loadBut setTitle:@"开始下载" forState:UIControlStateNormal];    }];        [self.outputStream close];    self.outputStream=nil;        self.task=nil;    }//判断文件现在已经下载了多少-(NSInteger) getCurrentDownloadSize{        NSDictionary *dict=[[NSFileManager defaultManager] attributesOfItemAtPath:[HQFilePath stringByAppendingPathComponent:HQFileName] error:nil];        return [dict[@"NSFileSize"] integerValue];    }@end





1 0
原创粉丝点击