NSURLConnection
继承 UIController
@interface LConnectionController ()<NSURLConnectionDataDelegate>
@property (weak, nonatomic) IBOutlet UIProgressView *myProgress;
@property (weak, nonatomic) IBOutlet UILabel *stateLabel;
// 用来写数据的文件句柄对象
@property (nonatomic,strong) NSFileHandle *writeHandle;
// 文件的总长度
@property (nonatomic,assign) long long totalLength;
// 当前已经写入的总大小
@property (nonatomic,assign) long long currentLength;
// 链接对象
@property (nonatomic,strong) NSURLConnection *connection;
@end
@implementation LConnectionController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor lightGrayColor];
}
#pragma mark NSURLConnectionDataDelegate
// 请求失败时调用(请求超时、网络异常)
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"fail11111111111111");
}
// 接收到服务器的响应就会调用
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// 如果文件已经存在,不执行以下操作
if (self.currentLength) return;
// 文件路径
NSString *ceches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filepath = [ceches stringByAppendingPathComponent:response.suggestedFilename];
// 创建一个空的文件到沙盒中
NSFileManager *mgr = [NSFileManager defaultManager];
[mgr createFileAtPath:filepath contents:nil attributes:nil];
// 创建一个用来写数据的文件句柄对象
self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
// 获得文件的总大小
self.totalLength = response.expectedContentLength;
NSLog(@"2222222222222222");
}
// 当接收到服务器返回的实体数据时调用(具体内容,这个方法可能会被调用多次)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// 移动到文件的最后面
[self.writeHandle seekToEndOfFile];
// 将数据写入沙盒
[self.writeHandle writeData:data];
// 累计写入文件的长度
self.currentLength += data.length;
// 下载进度
self.myProgress.progress = (double)self.currentLength / self.totalLength;
self.stateLabel.text = [NSString stringWithFormat:@"当前下载进度:%f",(double)self.currentLength / self.totalLength];
NSLog(@"333333333333");
}
// 加载完毕后调用(服务器的数据已经完全返回后)
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[[[UIAlertView alloc] initWithTitle:@"下载完成" message:@"已成功下载文件" delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil] show];
self.currentLength = 0;
self.totalLength = 0;
// 关闭文件
[self.writeHandle closeFile];
self.writeHandle = nil;
NSLog(@"4444444444444");
}
#pragma mark 按钮点击事件
- (IBAction)connectionDidClicked:(UIButton *)sender {
NSLog(@"按钮点击事件555555555");
// 状态取反
sender.selected = !sender.isSelected;
// 断点续传(断点下载)
if (sender.selected) { // 继续(开始)下载
NSURL *url = [NSURL URLWithString:@"http://dlsw.baidu.com/sw-search-sp/soft/9d/25765/sogou_mac_32c_V3.2.0.1437101586.dmg"];
// 2.请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置请求头
NSString *range = [NSString stringWithFormat:@"bytes=%lld-", self.currentLength];
[request setValue:range forHTTPHeaderField:@"Range"];
// 3.下载
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
}else{ // 暂停
[self.connection cancel];
self.connection = nil;
}
}
@end
2------
NSURLSession
继承 UIController
@interface LSessionController ()<NSURLSessionDownloadDelegate>
@property (weak, nonatomic) IBOutlet UILabel *stateLabel;
@property (weak, nonatomic) IBOutlet UIProgressView *myProgress;
// 下载任务
@property (nonatomic,strong) NSURLSessionDownloadTask *downloadTask;
// 记录下载的位置
@property (nonatomic,strong) NSData *resumeData;
@property (nonatomic,strong) NSURLSession *session;
@end
@implementation LSessionController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
}
- (NSURLSession *)session
{
if (!_session) {
NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
// 从0 开始下载
- (void)startDownload
{
NSURL *url = [NSURL URLWithString:@"http://dlsw.baidu.com/sw-search-sp/soft/9d/25765/sogou_mac_32c_V3.2.0.1437101586.dmg"];
// 创建任务
self.downloadTask = [self.session downloadTaskWithURL:url];
// 开始任务
[self.downloadTask resume];
}
// 恢复下载
- (void)resume
{
// 传入上次暂停下载返回的数据,就可以恢复下载
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
// 开始任务
[self.downloadTask resume];
self.resumeData = nil;
}
// 暂停
- (void)pause
{
__weak typeof(self) selfVc = self;
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
// resumeData : 包含了继续下载的开始的位置/下载的url
selfVc.resumeData = resumeData;
selfVc.downloadTask = nil;
}];
}
#pragma mark NSURLSessionDownloadDelegate
// 下载完毕会调用 location 文件临时地址
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
NSLog(@"11111下载完毕11111");
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// response.suggestedFilename: 建议使用的文件名,一般跟服务器端的文件名一致
NSString *file = [caches stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
// 将临时文件剪切或者复制Caches文件夹
NSFileManager *mgr = [NSFileManager defaultManager];
// AtPath : 剪切前的文件路径
// ToPath : 剪切后的文件路径
[mgr moveItemAtPath:location.path toPath:file error:nil];
// 提示下载完成
[[[UIAlertView alloc] initWithTitle:@"下载完成" message:downloadTask.response.suggestedFilename delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil] show];
}
// 每次写入沙盒完毕调用
// 在这里监听下载进度,totalBytesWritten / totalBytesExpectedToWrite
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
NSLog(@"22222222222");
self.myProgress.progress = (double)totalBytesWritten / totalBytesExpectedToWrite;
self.stateLabel.text = [NSString stringWithFormat:@"下载进度:%f",(double)totalBytesWritten / totalBytesExpectedToWrite];
}
// 恢复下载后调用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
NSLog(@"333333恢复下载后调用3333333");
}
#pragma mark 按钮点击事件
- (IBAction)sessionDidClicked:(UIButton *)sender
{
// 按钮状态取反
sender.selected = ! sender.isSelected;
if (!self.downloadTask) { // 开始(继续)下载
if (self.resumeData) { // 继续下载
[self resume];
}else{ // 从0开始下载
[self startDownload];
}
}else{ // 暂停
[self pause];
}
}
@end