iOS 下载功能:断点下载(暂停和开始)(NSURLConnectionDataDelegate方法)
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];
}
}
iOS 下载功能:断点下载(暂停和开始)(NSURLConnectionDataDelegate方法)的更多相关文章
- iOS 大文件断点下载
iOS 在下载大文件的时候,可能会因为网络或者人为等原因,使得下载中断,那么如何能够进行断点下载呢? // resumeData的文件路径 #define XMGResumeDataFile [[NS ...
- Android -- 多线程下载, 断点下载
1. 原理图 2. 示例代码 需要权限 <uses-permission android:name="android.permission.INTERNET"/> &l ...
- iOS开发网络请求——大文件的多线程断点下载
iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大 ...
- iOS开发中文件的上传和下载功能的基本实现-备用
感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...
- Java实现多线程断点下载(下载过程中可以暂停)
线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配. ...
- iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充
一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...
- iOS开发网络篇—大文件的多线程断点下载
http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时 ...
- iOS开发网络篇—大文件的多线程断点下载(转)
http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了 ...
- iOS开发网络篇—多线程断点下载
iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...
- ios开发视频播放后台下载功能实现 :1,ios播放视频 ,包含基于AVPlayer播放器,2,实现下载,iOS后台下载(多任务同时下载,单任务下载,下载进度,下载百分比,文件大小,下载状态)(真机调试功能正常)
ABBPlayerKit ios开发视频播放后台下载功能实现 : 代码下载地址:https://github.com/niexiaobo/ABBPlayerKit github资料学习和下载地址:ht ...
随机推荐
- 开发板 Linux驱动视频 驱动是什么
内存管理单元很重要. linux把设备看成文件,(open,read,write,ioctrl,close)主要写这几个函数. 哈弗结构,取指令和取数据同时进行. arm处理器体系架构以及发展方向 单 ...
- JS错误记录 - 事件 - 拖拽
错误总结: 1. var disX = 0; 现在window.onload里声明变量,而不是在事件oDiv.onmousedown里面声明并赋值. 对于这个还不是很明白. 2. onmoused ...
- var let 区别
var a = 5; var b = 10; if (a === 5) { let a = 4; // if 块级作用域 var b = 1; // 函数级作用域 console.log(a); // ...
- java.util.ConcurrentModificationException(如何避免ConcurrentModificationException)
java.util.ConcurrentModificationException is a very common exception when working with java collecti ...
- ssi的使用 开启 配置等
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/lsfhack/article/details/69664402ssi的定义SSI(Server Si ...
- eclipse启动tomcat报错
错误信息: 严重: A child container failed during start java.util.concurrent.ExecutionException: org.apach ...
- CSDN学院 免费技术答疑公开课,本周三场即将开播~~~
为了酬谢广大学员.CSDN学院特推出免费技术答疑公开课,让您开启一段充实的学习之旅~ 本周三场即将开播! ----------------------------------------------- ...
- [Nuxt] Add CSS Libraries to Nuxt
You can easily add CSS libraries to Nuxt using yarn or npm to install them, then simply adding them ...
- Eclipse 快捷键大全 分类: C_OHTERS 2014-06-01 13:05 332人阅读 评论(0) 收藏
精选常用: 1. ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母,比如a ...
- 在shell脚本中调用sqlplus 分类: H2_ORACLE 2013-06-23 13:01 1437人阅读 评论(0) 收藏
#!/bin/bash sqlplus dc_file_data_js/dc_file_data_js << EOF1 set linesize 500; set pagesize 100 ...