断点下载/断点续传

来源:互联网 发布:刷机后恢复数据 编辑:程序博客网 时间:2024/06/11 03:11
1------

NSURLConnection



继承 UIController


@interface LConnectionController ()<NSURLConnectionDataDelegate>


@property (weak,nonatomic) IBOutletUIProgressView *myProgress;

@property (weak,nonatomic) IBOutletUILabel *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 {

    [superviewDidLoad];

    self.view.backgroundColor = [UIColorlightGrayColor];

}

#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 = [cechesstringByAppendingPathComponent:response.suggestedFilename];

    

    // 创建一个空的文件到沙盒中

    NSFileManager *mgr = [NSFileManagerdefaultManager];

    [mgr createFileAtPath:filepathcontents:nilattributes:nil];

    

    // 创建一个用来写数据的文件句柄对象

    self.writeHandle = [NSFileHandlefileHandleForWritingAtPath:filepath];

    

    // 获得文件的总大小

    self.totalLength = response.expectedContentLength;

    NSLog(@"2222222222222222");

}


// 当接收到服务器返回的实体数据时调用(具体内容,这个方法可能会被调用多次)

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

    // 移动到文件的最后面

    [self.writeHandleseekToEndOfFile];

    // 将数据写入沙盒

    [self.writeHandlewriteData:data];

    // 累计写入文件的长度

    self.currentLength += data.length;

    // 下载进度

    self.myProgress.progress = (double)self.currentLength / self.totalLength;

    self.stateLabel.text = [NSStringstringWithFormat:@"当前下载进度:%f",(double)self.currentLength / self.totalLength];

    NSLog(@"333333333333");

}

// 加载完毕后调用(服务器的数据已经完全返回后)

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

    [[[UIAlertViewalloc] initWithTitle:@"下载完成"message:@"已成功下载文件"delegate:selfcancelButtonTitle:@"知道了"otherButtonTitles:nil]show];

    

    self.currentLength =0;

    self.totalLength =0;

    

    // 关闭文件

    [self.writeHandlecloseFile];

    self.writeHandle =nil;

    NSLog(@"4444444444444");

}


#pragma mark 按钮点击事件

- (IBAction)connectionDidClicked:(UIButton *)sender {

    NSLog(@"按钮点击事件555555555");

    // 状态取反

    sender.selected = !sender.isSelected;

    // 断点续传(断点下载)

    if (sender.selected) {// 继续(开始)下载

        

        NSURL *url = [NSURLURLWithString:@"http://dlsw.baidu.com/sw-search-sp/soft/9d/25765/sogou_mac_32c_V3.2.0.1437101586.dmg"];

        // 2.请求

        NSMutableURLRequest *request = [NSMutableURLRequestrequestWithURL:url];

        // 设置请求头

        NSString *range = [NSStringstringWithFormat:@"bytes=%lld-",self.currentLength];

        [request setValue:rangeforHTTPHeaderField:@"Range"];

        // 3.下载

        self.connection = [NSURLConnectionconnectionWithRequest:requestdelegate:self];

        

    }else{     // 暂停

        [self.connectioncancel];

        self.connection =nil;

    }

    

}


@end

图片加载失败


2------

NSURLSession


继承 UIController


@interface LSessionController ()<NSURLSessionDownloadDelegate>

@property (weak,nonatomic) IBOutletUILabel *stateLabel;

@property (weak,nonatomic) IBOutletUIProgressView *myProgress;

// 下载任务

@property (nonatomic,strong)NSURLSessionDownloadTask *downloadTask;

// 记录下载的位置

@property (nonatomic,strong)NSData *resumeData;

@property (nonatomic,strong)NSURLSession *session;



@end


@implementation LSessionController


- (void)viewDidLoad {

    [superviewDidLoad];

    self.view.backgroundColor = [UIColororangeColor];

}


- (NSURLSession *)session

{

    if (!_session) {

        NSURLSessionConfiguration *cfg = [NSURLSessionConfigurationdefaultSessionConfiguration];

        self.session = [NSURLSessionsessionWithConfiguration:cfgdelegate:selfdelegateQueue:[NSOperationQueuemainQueue]];

    }

    return_session;

}


// 0开始下载

- (void)startDownload

{

    NSURL *url = [NSURLURLWithString:@"http://dlsw.baidu.com/sw-search-sp/soft/9d/25765/sogou_mac_32c_V3.2.0.1437101586.dmg"];

    // 创建任务

    self.downloadTask = [self.sessiondownloadTaskWithURL:url];

    // 开始任务

    [self.downloadTaskresume];

}


// 恢复下载

- (void)resume

{

    // 传入上次暂停下载返回的数据,就可以恢复下载

    self.downloadTask = [self.sessiondownloadTaskWithResumeData:self.resumeData];

    // 开始任务

    [self.downloadTaskresume];

    self.resumeData =nil;

    

}

// 暂停

- (void)pause

{

    __weaktypeof(self) selfVc =self;

    [self.downloadTaskcancelByProducingResumeData:^(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 = [cachesstringByAppendingPathComponent:downloadTask.response.suggestedFilename];

    // 将临时文件剪切或者复制Caches文件夹

    NSFileManager *mgr = [NSFileManagerdefaultManager];

    

    // AtPath : 剪切前的文件路径

    // ToPath : 剪切后的文件路径

    [mgr moveItemAtPath:location.pathtoPath:file error:nil];

    // 提示下载完成

    [[[UIAlertViewalloc] initWithTitle:@"下载完成"message:downloadTask.response.suggestedFilenamedelegate:selfcancelButtonTitle:@"知道了"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 = [NSStringstringWithFormat:@"下载进度:%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


图片加载失败



0 0