美文网首页收藏iosiOS way, life wayiOS技术专题
OC网络:NSURLSessionDataTask实现离线断点下

OC网络:NSURLSessionDataTask实现离线断点下

作者: cyh老崔 | 来源:发表于2015-12-10 16:02 被阅读611次

NSURLSessionDataDelegate代理方法实现离线断点下载,即程序意外退出时,再登陆,可以根据上次的进度继续下载.

原理:

  • 边下载边写入到caches
  • 每次开启下载时,设置请求头的信息:下载的位置.

#define KfileName @"123.mp4"

@interface ViewController ()<NSURLSessionDataDelegate>
@property (weak, nonatomic) IBOutlet UILabel *label;

@property (weak, nonatomic) IBOutlet UIProgressView *progress;
/** currentsize */
@property (nonatomic, assign) NSInteger currentSize;
@property (nonatomic, assign) NSInteger totalSize;
/** dataTask */
@property (nonatomic, strong) NSURLSessionDataTask *dataTask;
/** outPutStream */
@property (nonatomic, strong) NSOutputStream *outPutStream;

@end

@implementation ViewController

#pragma mark -------------------------------
#pragma mark Events
- (IBAction)startBtnClick:(id)sender {
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    //确定是否存在已经下载的文件,如存在,继续下载.
    self.currentSize = [self getSize];
    
    //new dataTask
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    //设置请求头信息
    NSString *header = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
    [request setValue:header forHTTPHeaderField:@"Range"];
    
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
    self.dataTask = dataTask;
    
    [self.dataTask resume];
}
- (IBAction)suspendBtnClick:(id)sender {
    [self.dataTask suspend];
}


- (IBAction)continueBtnClick:(id)sender {
    [self.dataTask resume];
}

#pragma mark -------------------------------
#pragma mark methods
- (NSInteger)getSize{
    //0.拼接文件全路径
    NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:KfileName];
    
    //先把沙盒中的文件大小取出来
    NSDictionary *dict = [[NSFileManager defaultManager]attributesOfItemAtPath:fullPath error:nil];
    NSInteger size = [[dict objectForKey:@"NSFileSize"]integerValue];
    return size;
}

#pragma mark -------------------------------
#pragma mark NSURLSessionDataDelegate

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
    
    //此处注意,不设置为allow,其它delegate methods将不被执行
    completionHandler(NSURLSessionResponseAllow);
    
    self.totalSize = response.expectedContentLength + self.currentSize;
    
    //0.拼接文件全路径
    
    NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:KfileName];
    
    //1.创建输出流
    NSOutputStream *outPutStream = [NSOutputStream outputStreamToFileAtPath:fullPath append:YES];
    [outPutStream open];
    self.outPutStream = outPutStream;
}

//2.当接受到服务器返回的数据的时候调用,会调用多次
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
    
    self.currentSize += data.length;
    CGFloat rate = 1.0 * self.currentSize / self.totalSize;
    self.progress.progress = rate;
    self.label.text = [NSString stringWithFormat:@"%.2f", rate];
    [self.outPutStream write:data.bytes maxLength:data.length];
    
}

//3.当整个请求结束的时候调用,error有值的话,那么说明请求失败
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    
    [self.outPutStream close];
    self.outPutStream = nil;
}

@end

细节未完全处理:btn的enable状态,方法抽取等.

相关文章

网友评论

  • 黑幕居士:不知为什么,请求到的文件总长度 (response.expectedContentLength) 只有几字节,瞬间就100%,文件也没下完
    黑幕居士:@老司机Wicky 是的,我抄完你的代码后, 把=改成空格, 就能完整下载
    老司机Wicky:@黑幕居士 你是说把range里面的=去掉么
    黑幕居士:@黑幕居士 终于找到原因了,把 @"bytes=%zd-" 改成 @"bytes %zd-"就能正常下载了
  • 257f312dccb8: 你好 有完整的例子 能发一份学习学习吗? wb911025@163.com 谢谢

本文标题:OC网络:NSURLSessionDataTask实现离线断点下

本文链接:https://www.haomeiwen.com/subject/tllyhttx.html