Created
February 15, 2017 13:25
-
-
Save leo493852107/86d5f5be550641ea0e6c250348f30189 to your computer and use it in GitHub Desktop.
大文件断点下载
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.m | |
// 005-urlsession | |
// | |
// Created by 李建舜 on 15/02/2017. | |
// Copyright © 2017 李建舜. All rights reserved. | |
// | |
#import "ViewController.h" | |
#import "NSString+Hash.h" | |
#import "UIImageView+WebCache.h" | |
// 所需要下载的文件的url | |
#define JSFileURL @"http://video.pearvideo.com/mp4/short/20170215/cont-1034279-10200514-hd.mp4" | |
// 文件名(沙盒中的文件名) | |
#define JSFileName JSFileURL.md5String | |
// 文件存放的路径 | |
#define JSFileFullPath [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:JSFileName] | |
// 存储文件总长度的文件路径(caches) | |
#define JSTotalLengthFullPath [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"totalLength.leo"] | |
// 文件的已下载的长度 | |
#define JSDownloadLength [[[NSFileManager defaultManager] attributesOfItemAtPath:JSFileFullPath error:nil][NSFileSize] integerValue] | |
@interface ViewController () <NSURLSessionDataDelegate> | |
/** 下载任务 */ | |
@property (nonatomic, strong) NSURLSessionDataTask *task; | |
/** 保存上次下载信息 */ | |
//@property (nonatomic, strong) NSData *resumeData; | |
/** session */ | |
@property (nonatomic, strong) NSURLSession *session; | |
/** 写文件的流对象 */ | |
@property (nonatomic, strong) NSOutputStream *stream; | |
/** 文件的总长度 */ | |
@property (nonatomic, assign) NSInteger totalLength; | |
@end | |
@implementation ViewController | |
- (NSURLSession *)session | |
{ | |
if (!_session) { | |
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]]; | |
} | |
return _session; | |
} | |
- (NSOutputStream *)stream { | |
if (!_stream) { | |
_stream = [NSOutputStream outputStreamToFileAtPath:JSFileFullPath append:YES]; | |
} | |
return _stream; | |
} | |
- (NSURLSessionDataTask *)task { | |
if (!_task) { | |
NSInteger totalLength = [[NSDictionary dictionaryWithContentsOfFile:JSTotalLengthFullPath][JSFileName] integerValue]; | |
if (totalLength && JSDownloadLength == totalLength) { | |
NSLog(@"--文件已下载--"); | |
return nil; | |
} | |
// 创建请求 | |
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://video.pearvideo.com/mp4/short/20170215/cont-1034279-10200514-hd.mp4"]]; | |
// 设置请求头 | |
// Range : bytes=xxx-xxx | |
NSString *range = [NSString stringWithFormat:@"bytes=%zd-", JSDownloadLength]; | |
[request setValue:range forHTTPHeaderField:@"Range"]; | |
// 创建一个Data任务 | |
_task = [self.session dataTaskWithRequest:request]; | |
} | |
return _task; | |
} | |
// 开始下载 | |
- (IBAction)start:(id)sender { | |
[self.task resume]; | |
} | |
// 暂停下载 | |
- (IBAction)pause:(id)sender { | |
[self.task suspend]; | |
} | |
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
} | |
#pragma mark - NSURLSessionDataDelegate | |
/** | |
* 接收到响应 | |
*/ | |
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { | |
// 打开流 | |
[self.stream open]; | |
// 获得服务器这次请求返回数据的总长度 + 文件现在的长度 | |
self.totalLength = [response.allHeaderFields[@"Content-Length"] integerValue] + JSDownloadLength; | |
// 存储总长度 | |
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:JSTotalLengthFullPath]; | |
if (dict == nil) { | |
dict = [NSMutableDictionary dictionary]; | |
} | |
dict[JSFileName] = @(self.totalLength); | |
[dict writeToFile:JSTotalLengthFullPath atomically:YES]; | |
// 允许接受服务器的数据 | |
completionHandler(NSURLSessionResponseAllow); | |
} | |
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { | |
// 写入数据 | |
[self.stream write:[data bytes] maxLength:data.length]; | |
// 下载进度 | |
NSLog(@"%.2f", 1.0 * JSDownloadLength / self.totalLength); | |
} | |
/* | |
* 请求完毕 | |
*/ | |
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task | |
didCompleteWithError:(nullable NSError *)error { | |
// 关闭流 | |
[self.stream close]; | |
self.stream = nil; | |
// 清除任务 | |
self.task = nil; | |
} | |
- (void)didReceiveMemoryWarning { | |
[super didReceiveMemoryWarning]; | |
// Dispose of any resources that can be recreated. | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment