// 所需要下载的文件的URL
#define FileURL @"http://apk.r1.market.hiapk.com/data/upload/apkres/2016/3_23/10/com.dailyyoga.cn_102411.apk"
// 文件名(沙盒中的文件名)
#define Filename [self md5String:FileURL]
// 文件的存放路径(caches)
#define FileFullpath [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:Filename]
// 存储文件总长度的文件路径(caches)
#define TotalLengthFullpath [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"totalLength.plist"]
// 文件的已下载长度
#define DownloadLength [[[NSFileManager defaultManager] attributesOfItemAtPath:FileFullpath error:nil][NSFileSize] integerValue]
#import "ViewController.h"
#import "UIImageView+WebCache.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonHMAC.h>
@interface ViewController () <NSURLSessionDataDelegate>
/** 下载任务 */
@property (nonatomic, strong) NSURLSessionDataTask *task;
/** 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:FileFullpath append:YES];
}
return _stream;
}
- (NSURLSessionDataTask *)task
{
if (!_task) {
NSInteger totalLength = [[NSDictionary dictionaryWithContentsOfFile:TotalLengthFullpath][Filename] integerValue];
if (totalLength && DownloadLength == totalLength) {
NSLog(@"----文件已经下载过了");
return nil;
}
// 创建请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:FileURL]];
// 设置请求头
// Range : bytes=xxx-xxx
NSString *range = [NSString stringWithFormat:@"bytes=%zd-", DownloadLength];
[request setValue:range forHTTPHeaderField:@"Range"];
// 创建一个Data任务
_task = [self.session dataTaskWithRequest:request];
}
return _task;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"%@", FileFullpath);
}
/**
* 开始下载
*/
- (IBAction)start:(id)sender {
// 启动任务
[self.task resume];
}
/**
* 暂停下载
*/
- (IBAction)pause:(id)sender {
[self.task suspend];
}
#pragma mark - <NSURLSessionDataDelegate>
/**
* 1.接收到响应
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
// 打开流
[self.stream open];
// 获得服务器这次请求 返回数据的总长度
self.totalLength = [response.allHeaderFields[@"Content-Length"] integerValue] + DownloadLength;
// 存储总长度
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:TotalLengthFullpath];
if (dict == nil) dict = [NSMutableDictionary dictionary];
dict[Filename] = @(self.totalLength);
[dict writeToFile:TotalLengthFullpath atomically:YES];
// 接收这个请求,允许接收服务器的数据
completionHandler(NSURLSessionResponseAllow);
}
/**
* 2.接收到服务器返回的数据(这个方法可能会被调用N次)
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
// 写入数据
[self.stream write:data.bytes maxLength:data.length];
// 下载进度
NSLog(@"%f", 1.0 * DownloadLength / self.totalLength);
}
/**
* 3.请求完毕(成功\失败)
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
// 关闭流
[self.stream close];
self.stream = nil;
// 清除任务
self.task = nil;
}
- (NSString *)md5String:(NSString *)str
{
const char *string = str.UTF8String;
int length = (int)strlen(string);
unsigned char bytes[CC_MD5_DIGEST_LENGTH];
CC_MD5(string, length, bytes);
return [self stringFromBytes:bytes length:CC_MD5_DIGEST_LENGTH];
}
- (NSString *)stringFromBytes:(unsigned char *)bytes length:(int)length
{
NSMutableString *mutableString = @"".mutableCopy;
for (int i = 0; i < length; i++)
[mutableString appendFormat:@"%02x", bytes[i]];
return [NSString stringWithString:mutableString];
}
@end
NSURLSession断点下载笔记
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- qNSURLSession系列笔记:NSURLSession笔记 上传文件 使用NSURLSession下载文件 ...
- 从iOS7以来,苹果推出NSURLSession后,iOS现在可以实现真正的后台下载,这对我们iOSer来说是一个...
- 一.概述 NSURLSession始于ios7.它具有访问接口,上传/下载数据,断点继传和后台下载等功能:其使用步...
- 本文参考:iOS-FMDB - 简书 Kill应用之后断点续传的实现 - 简书 另外一篇文章思路很像:基于iOS...
- 在生活中,我们有时会遇到那种喜欢胡乱指挥却又不得要领的人,这时候可能就会有人抱怨了:你们看看这个人,好好的事情被他...