断点下载/断点续传

1------

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

断点下载/断点续传_第1张图片


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


断点下载/断点续传_第2张图片



你可能感兴趣的:(关键代码块-Demo)