您的位置:首页 > 移动开发 > IOS开发

iOS 下载功能:断点下载(暂停和开始)(NSURLConnectionDataDelegate方法)

2015-07-13 12:30 831 查看
1,model文件代码

文件名称:HMFileDownloader.h

#import <Foundation/Foundation.h>

@interface HMFileDownloader : NSObject

/**

* 所需要下载文件的远程URL(连接服务器的路径)

*/

@property (nonatomic, copy) NSString *url;

/**

* 文件的存储路径(文件下载到什么地方)

*/

@property (nonatomic, copy) NSString *destPath;

/**

* 是否正在下载(有没有在下载, 只有下载器内部才知道)

*/

@property (nonatomic, readonly, getter = isDownloading) BOOL downloading;

/**

* 用来监听下载进度

*/

@property (nonatomic, copy) void (^progressHandler)(double progress);

/**

* 用来监听下载完毕

*/

@property (nonatomic, copy) void (^completionHandler)();

/**

* 用来监听下载失败

*/

@property (nonatomic, copy) void (^failureHandler)(NSError *error);

/**

* 开始(恢复)下载

*/

- (void)start;

/**

* 暂停下载

*/

- (void)pause;

@end

文件名称:HMFileDownloader.m

#import "HMFileDownloader.h"

@interface HMFileDownloader() <NSURLConnectionDataDelegate>

/**

* 连接对象

*/

@property (nonatomic, strong) NSURLConnection *conn;

/**

* 写数据的文件句柄

*/

@property (nonatomic, strong) NSFileHandle *writeHandle;

/**

* 当前已下载数据的长度

*/

@property (nonatomic, assign) long long currentLength;

/**

* 完整文件的总长度

*/

@property (nonatomic, assign) long long totalLength;

@end

@implementation HMFileDownloader

/**

* 开始(恢复)下载

*/

- (void)start

{

NSURL *url = [NSURL URLWithString:self.url];

// 默认就是GET请求

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

// 设置请求头信息

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

[request setValue:value forHTTPHeaderField:@"Range"];

self.conn = [NSURLConnection connectionWithRequest:request delegate:self];

_downloading = YES;

}

/**

* 暂停下载

*/

- (void)pause

{

[self.conn cancel];

self.conn = nil;

_downloading = NO;

}

#pragma mark - NSURLConnectionDataDelegate 代理方法

/**

* 1. 当接受到服务器的响应(连通了服务器)就会调用

*/

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

#warning 一定要判断

if (self.totalLength) return;

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

NSFileManager *mgr = [NSFileManager defaultManager];

// 刚创建完毕的大小是0字节

[mgr createFileAtPath:self.destPath contents:nil attributes:nil];

// 2.创建写数据的文件句柄

self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:self.destPath];

// 3.获得完整文件的长度

self.totalLength = response.expectedContentLength;

}

/**

* 2. 当接受到服务器的数据就会调用(可能会被调用多次, 每次调用只会传递部分数据)

*/

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

{

// 累加长度

self.currentLength += data.length;

NSLog(@"=%lld==",self.currentLength);

// 显示进度

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

if (self.progressHandler) { // 传递进度值给block

self.progressHandler(progress);

}

// 移动到文件的尾部

[self.writeHandle seekToEndOfFile];

// 从当前移动的位置(文件尾部)开始写入数据

[self.writeHandle writeData:data];

}

/**

* 3. 当服务器的数据接受完毕后就会调用

*/

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

// 清空属性值

self.currentLength = 0;

self.totalLength = 0;

if (self.currentLength == self.totalLength) {

// 关闭连接(不再输入数据到文件中)

[self.writeHandle closeFile];

self.writeHandle = nil;

}

if (self.completionHandler) {

self.completionHandler();

}

}

/**

* 请求错误(失败)的时候调用(请求超时\断网\没有网, 一般指客户端错误)

*/

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

if (self.failureHandler) {

self.failureHandler(error);

}

}

@end

2、将上述两个文件拖到工程中

3、在控制器文件中导入

#import "HMFileDownloader.h"

声明

@property (nonatomic, strong)NSString *url;

@property (retain, nonatomic) UIProgressView *progressView;

@property (nonatomic, strong) HMFileDownloader *fileDownloader;

- (void)viewDidLoad

{

_progressView=[[UIProgressView alloc]init];

_progressView.frame=CGRectMake(10, 150, 170, 20);

[self.view addSubview:_progressView];

[self fileDownloader];

}

- (void)fileDownloader

{

if (!_ViewCont.fileDownloader) {

_fileDownloader = [[HMFileDownloader alloc] init];

// 需要下载的文件远程URL

_fileDownloader.url = @"http://192.168.1.9:8080/wyhouAppServices/upload/app_user/iOS%207%20Cookbook.pdf";

// 文件保存到什么地方1

NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

NSString *filepath = [caches stringByAppendingPathComponent:@"20Cookbook.pdf"];

// 文件保存到什么地方2

NSURL *targetURL = [NSURL URLWithString:_ViewCont.fileDownloader.url];

NSString *docPath = [self documentsDirectoryPath];

// Combine the filename and the path to the documents dir into the full path

NSString *pathToDownloadTo = [NSString stringWithFormat:@"%@/%@", docPath, [targetURL lastPathComponent]];

_fileDownloader.destPath = pathToDownloadTo;

// typeof(10) a = 20; // int a = 20;

__weak typeof(self) vc = self;

_fileDownloader.progressHandler = ^(double progress) {

vc.progressView.progress=progress;

// _progressView.progress = progress;

};

_fileDownloader.completionHandler = ^{

NSLog(@"------下载完毕");

};

_fileDownloader.failureHandler = ^(NSError *error){

};

}else{

_progressView.progress= _ViewCont.progressView.progress;

__weak typeof(self) vc = self;

_fileDownloader.progressHandler = ^(double progress) {

vc.progressView.progress=progress;

//

};

NSLog(@"------");

}

// return _fileDownloader;

}

-(void)dealloc{

_progressView.progress=_progressView.progress;

}

// 按钮文字: "开始", "暂停"

- (void)start { // self.currentLength == 200

if (_fileDownloader.isDownloading) { // 暂停下载

[_fileDownloader pause];

[_testBtn setTitle:@"恢复" forState:UIControlStateNormal];

} else { // 开始下载

[_fileDownloader start];

[_testBtn setTitle:@"暂停" forState:UIControlStateNormal];

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: