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 ...
随机推荐
- 解决Win8/8.1无法正确识别USB3.0的问题
找一个USB3.0的移动硬盘到了手里竟然变成2.0的了!二了! 不能忍啊. 听说是快速启动的问题,但是开机速度快很诱人. 百度了其他解决方法,终于解决了. 下面摘录自: http://blog.csd ...
- 大家好,我是FansUnion,雷文
友情提示 以下是我在CSDN Code讨论组的自我介绍. 很多CSDN网友,总是重复地问我一些比较常见的问题. 我已经开始机械性地回答网友的问题了. 自我介绍 我的CSDN等媒体的ID,大多带有Fan ...
- Jquery+Ajax+Bootstrap Paginator实现分页的拼接
效果图如下 jsp页面引入bootstrap样式,jquery和bootstrap-paginator.js <link type="text/css" rel=" ...
- amazeui学习笔记--css(常用组件3)--按钮组Button-group
amazeui学习笔记--css(常用组件3)--按钮组Button-group 一.总结 1.按钮组用法:把一系列要使用的 .am-btn 按钮放入 .am-btn-group . 2.按钮工具栏: ...
- Android 监听软键盘点击回车及换行事件
mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean ...
- 编程一一C语言问题,指针函数与函数指针
资料来源于网上: 一.指针函数:指返回值是指针的函数 类型标识符 *函数名(参数表) int *f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个地址值.函数返 ...
- Hamming correct
从数的最左边开始,并标记为1 将2的平方的位置留出来,做为校验位例如,8位2进制数10011010===>_ _ 1 _ 0 0 1 _ 1 0 1 0 位置1用来校验最右边的位位1的位置1 3 ...
- 实现span设置宽度(行内元素本来不支持调宽度高度这些样式)(变成行内块元素:display:inline-block;)
实现span设置宽度(行内元素本来不支持调宽度高度这些样式)(变成行内块元素:display:inline-block;) 一.总结 1.将span从行内元素变成行内快元素就可以调了: 设置样式的时候 ...
- linux目录架构及常用的基本命令
linux目录架构 / 根目录 /bin 常用的命令 binary file 的目錄 /boot 存放系统启动时必须读取的档案,包括核心 (kernel) 在内 /boot/g ...
- FZU 2020 组合
组合数求模要用逆元,用到了扩展的欧几里得算法. #include<cstdio> int mod; typedef long long LL; void gcd(LL a,LL b,LL ...