利用NSURLSession完成的断点续传功能
首先是业务中的.h文件
#import <UIKit/UIKit.h>
#import "DenglSingleton.h" @protocol DownLoadVCdelegate <NSObject> -(void)DownloadCompletedWithIndex:(NSInteger)index; @end @interface DownLoadVC : UIViewController
DenglSingletonH(DownLoadVC)
@property (nonatomic,copy) NSDictionary *dic; @property (nonatomic,weak) id<DownLoadVCdelegate> delegate; @end
#import "DownLoadVC.h"
#import "UIView+denglFrame.h"
#import "DBBackgroundBtn.h"
#import "SVProgressHUD.h" #define dAllMusicPlistFilePath [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"text"] stringByAppendingPathComponent:@"allmusic.plist"]
#define filePath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:self.fileName] @interface DownLoadVC ()<NSURLSessionDataDelegate>
{
NSString *_downloadTag;
} @property (strong, nonatomic) UIImageView *iconImageView;
@property (strong, nonatomic) UIImageView *bottomImageView;
@property (strong, nonatomic) UITextView *AppDescritionTextView;
@property (strong, nonatomic) UILabel *AppNameLabel;
@property (strong, nonatomic) DBBackgroundBtn *downLoadBtn;
@property (nonatomic,strong) UIButton *backBtn;
@property (nonatomic,strong) UIImageView *backBtnImgView;
@property (nonatomic,copy) NSString *currentName; /** 下载任务 */
@property (nonatomic, strong) NSURLSessionDataTask *task;
/** session */
@property (nonatomic, strong) NSURLSession *session;
/** 写文件的流对象 */
@property (nonatomic, strong) NSOutputStream *stream;
/** 文件的总长度 */
@property (nonatomic, assign) NSInteger totalLength;
/** 文件百分比 */
@property (nonatomic, assign) float p;
/** 文件名字 */
@property (nonatomic, copy) NSString *fileName;
/** 文件url */
@property (nonatomic, strong) NSURL *url;
/** 下载数据保存字典 */
@property (nonatomic, strong) NSMutableDictionary *downloadingListDic;
@end @implementation DownLoadVC
DenglSingletonM(DownLoadVC) - (NSURLSession *)session
{
if (!_session) {
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
}
return _session;
} - (NSOutputStream *)stream
{
if (!_stream) {
_stream = [NSOutputStream outputStreamToFileAtPath:filePath append:YES];
}
return _stream;
} -(void)startDownloadMusic{
// 创建请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.url];
// 设置请求头
// Range : bytes=xxx-xxx
NSInteger downloadLength = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil][NSFileSize] integerValue];
NSString *range = [NSString stringWithFormat:@"bytes=%zd-", downloadLength];
[request setValue:range forHTTPHeaderField:@"Range"]; // 创建一个Data任务
self.task = [self.session dataTaskWithRequest:request];
// NSLog(@"test");
} -(void)setDic:(NSDictionary *)dic{
_dic = dic; self.fileName = [self.dic objectForKey:@"filename"];
self.url = [NSURL URLWithString:[self.dic objectForKey:@"url"]];
if (self.currentName == nil) {
//初始化UI
[self setUI];
self.currentName = self.fileName;
//取出上一次保存的下载进度
self.downloadingListDic = [NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults]objectForKey:@"downloadingListDic"]];
if (self.downloadingListDic == nil) {
self.downloadingListDic = [NSMutableDictionary dictionary];
[[NSUserDefaults standardUserDefaults] setObject:self.downloadingListDic forKey:@"downloadingListDic"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
self.p = [[self.downloadingListDic objectForKey:self.fileName] floatValue];
self.downLoadBtn.progress = self.p;
//
if (self.p != ) {
[self.downLoadBtn setBackgroundImage:[UIImage imageNamed:@"download_pause"] forState:UIControlStateNormal];
} }else{
if (![self.currentName isEqualToString:self.fileName]) {
//取消任务
self.currentName = self.fileName;
[self.session invalidateAndCancel];
self.session = nil;
//取出上一次保存的下载进度
self.downloadingListDic = [NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults]objectForKey:@"downloadingListDic"]];
if (self.downloadingListDic == nil) {
self.downloadingListDic = [NSMutableDictionary dictionary];
[[NSUserDefaults standardUserDefaults] setObject:self.downloadingListDic forKey:@"downloadingListDic"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
self.p = [[self.downloadingListDic objectForKey:self.fileName] floatValue];
self.downLoadBtn.progress = self.p;
//
if (self.p != ) {
[self.downLoadBtn setBackgroundImage:[UIImage imageNamed:@"download_pause"] forState:UIControlStateNormal];
}
self.downLoadBtn.tag = ;
}
}
[self setDataWithDic:dic];
} - (void)viewDidLoad {
[super viewDidLoad];
} -(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated]; [self.downloadingListDic setObject:[NSString stringWithFormat:@"%f",self.p] forKey:self.fileName]; [[NSUserDefaults standardUserDefaults] setObject:self.downloadingListDic forKey:@"downloadingListDic"];
[[NSUserDefaults standardUserDefaults]synchronize];
} -(void)setUI{
[[NSUserDefaults standardUserDefaults]setObject:@"no" forKey:@"begin"];
self.view.backgroundColor = [UIColor whiteColor]; //返回按钮
self.backBtn = [[UIButton alloc]init];
[self.backBtn addTarget:self action:@selector(clickBackBtn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.backBtn];
//
self.AppNameLabel = [[UILabel alloc]init];
self.AppNameLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.AppNameLabel];
//
self.AppDescritionTextView = [[UITextView alloc]init];
self.AppDescritionTextView.textColor = [UIColor grayColor];
self.AppDescritionTextView.editable = NO;
self.AppDescritionTextView.selectable = NO;
[self.view addSubview:self.AppDescritionTextView];
//
self.bottomImageView = [[UIImageView alloc]init];
[self.view addSubview:self.bottomImageView];
//
self.iconImageView = [[UIImageView alloc]init];
[self.view addSubview:self.iconImageView]; //
self.downLoadBtn = [[DBBackgroundBtn alloc]init];
[self.downLoadBtn setBackgroundImage:[UIImage imageNamed:@"download"] forState:UIControlStateNormal];
self.downLoadBtn.tag = ;
self.downLoadBtn.progress = ;
[self.downLoadBtn addTarget:self action:@selector(clickdownLoadBtn:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.downLoadBtn]; //
self.backBtnImgView = [[UIImageView alloc]init];
self.backBtnImgView.image = [UIImage imageNamed:@"back_ipad.png"];
[self.view addSubview:self.backBtnImgView]; } -(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[self setUIFrame];
} -(void)setUIFrame{
//下载按钮
self.downLoadBtn.width = / 1136.0 * self.view.height;
self.downLoadBtn.height = self.downLoadBtn.width;
self.downLoadBtn.x = (self.view.width - self.downLoadBtn.width)/;
self.downLoadBtn.y = / 1136.0 * self.view.height; //图标
self.iconImageView.width = / 1136.0 * self.view.height;
self.iconImageView.height = self.iconImageView.width;
self.iconImageView.x = (self.view.width - self.iconImageView.width)/;
self.iconImageView.y = / 1136.0 * self.view.height; //底部图
self.bottomImageView.width = self.view.width;
self.bottomImageView.height = / 1136.0 * self.view.height;
self.bottomImageView.x = ;
self.bottomImageView.y = / 1136.0 * self.view.height; //AppNameLabel app名称
self.AppNameLabel.width = self.view.width;
self.AppNameLabel.height = / 1136.0 * self.view.height;
self.AppNameLabel.x = ;
self.AppNameLabel.y = / 1136.0 * self.view.height;
self.AppNameLabel.font = [UIFont systemFontOfSize: / 1136.0 * self.view.height]; //AppDescritionTextView
self.AppDescritionTextView.x = / 1136.0 * self.view.height;
self.AppDescritionTextView.width = self.view.width - self.AppDescritionTextView.x * ;
self.AppDescritionTextView.height = / 1136.0 * self.view.height;
self.AppDescritionTextView.y = / 1136.0 * self.view.height;
[self.AppDescritionTextView scrollRangeToVisible:NSMakeRange(, )];
//
self.AppDescritionTextView.font = [UIFont systemFontOfSize: / 1136.0 * self.view.height]; //返回按钮
self.backBtn.width = ;
self.backBtn.height = ;
self.backBtn.x = ;
self.backBtn.y = ; // 15 8 12 25
self.backBtnImgView.width = / 568.0 * self.view.height;
self.backBtnImgView.height = / 568.0 * self.view.height;
self.backBtnImgView.x = / 568.0 * self.view.height;
self.backBtnImgView.y = / 568.0 * self.view.height;
} -(void)setDataWithDic:(NSDictionary*)dic{
//
NSString *iconImage = [dic objectForKey:@"image"];
self.iconImageView.image = [UIImage imageNamed:iconImage]; //
NSString *bottomImage = [dic objectForKey:@"color"];
self.bottomImageView.image = [UIImage imageNamed:bottomImage]; //
NSArray *AppNameArr = [dic objectForKey:@"name"];
NSInteger index = [[NSUserDefaults standardUserDefaults] integerForKey:@"yuyan"];
self.AppNameLabel.text = [AppNameArr objectAtIndex:index]; //
NSArray *AppDescritionArr = [dic objectForKey:@"info"];
self.AppDescritionTextView.text = [AppDescritionArr objectAtIndex:index];
} - (IBAction)clickdownLoadBtn:(id)sender {
UIButton *btn = sender;
if (btn.tag == ) {//下载
[self.downLoadBtn setBackgroundImage:[UIImage imageNamed:@"download"] forState:UIControlStateNormal];
[self startDownloadMusic];
[self.task resume];
_downloadTag = @"resume";
}else if (btn.tag == -){//停止
[self.downLoadBtn setBackgroundImage:[UIImage imageNamed:@"download_pause"] forState:UIControlStateNormal];
if (self.session) {
[self.session invalidateAndCancel];
self.session =nil;
}
_downloadTag = @"stop";
}
btn.tag *= -;
} -(void)dealloc{
} - (void)clickBackBtn {
[self.navigationController popViewControllerAnimated:YES];
} #pragma mark - NSURLSessionDataDelegate
/**
* 1.接收到响应
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
// 获得服务器这次请求 返回数据的总长度
NSInteger downloadLength = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil][NSFileSize] integerValue];
self.totalLength = [response.allHeaderFields[@"Content-Length"] integerValue] + downloadLength; // 打开流
[self.stream open];
// 接收这个请求,允许接收服务器的数据
completionHandler(NSURLSessionResponseAllow);
} /**
* 2.接收到服务器返回的数据
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
[self.stream write:data.bytes maxLength:data.length];
// 下载进度
NSInteger downloadLength = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil][NSFileSize] integerValue];
self.p = 1.0 * downloadLength / self.totalLength;
NSLog(@"%f",self.p);
dispatch_async(dispatch_get_main_queue(), ^{
self.downLoadBtn.progress = self.p;
});
} /**
* 3.请求完毕(成功\失败)
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
// 关闭流
[self.stream close];
self.stream = nil;
if (!error) {//没有错误信息
if (task.state == NSURLSessionTaskStateCompleted) {
NSLog(@"NSURLSessionTaskStateCompleted");
NSInteger index = [[self.dic objectForKey:@"index"] integerValue];
//下载完成后,将曲目的下载状态做一次更新,将新的数组更新到plist文件中。
NSMutableArray *arr = [NSMutableArray arrayWithContentsOfFile:dAllMusicPlistFilePath];
NSMutableDictionary *dic = [arr objectAtIndex:index];
[dic setObject:@"" forKey:@"isDownLoad"];
if ([arr writeToFile:dAllMusicPlistFilePath atomically:YES]) {
NSLog(@"writeToFileSuccess");
}
dispatch_async(dispatch_get_main_queue(), ^{
if (self.delegate && [self.delegate respondsToSelector:@selector(DownloadCompletedWithIndex:)]) {
[self.delegate DownloadCompletedWithIndex:index];
}
[self.navigationController popViewControllerAnimated:NO];
});
}
}else{//有错误信息
if (error.code == ) {
NSLog(@"用户取消");
}else{
[SVProgressHUD setMinimumDismissTimeInterval:3.5];
[SVProgressHUD setDefaultStyle:SVProgressHUDStyleDark];
NSString *str = NSLocalizedString(@"loadFaild", nil);
[SVProgressHUD showErrorWithStatus:str];
}
}
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
利用NSURLSession完成的断点续传功能的更多相关文章
- 利用其它带文件防护功能的软件防止*.asp;*.jpg写入文件。
此木马是一个.NET程序制作,如果你的服务器支持.NET那就要注意了,,进入木马有个功能叫:IIS Spy,点击以后可以看到所有站点所在的物理路径.以前有很多人提出过,但一直没有人给解决的答案.. 防 ...
- iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充
一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...
- chrome断点续传功能
刚好找到了一个临时的解决方法,chrome其实已经内部实现了断点续传功能,不过应该还没完善,所以要自己打开.方法:用chrome在地址栏输入chrome://flags用搜索找到resumption( ...
- [置顶] LOAD语句:利用MSSQL中的xp_cmdshell功能,将指定文件夹下的指定文件,生成mysql的LOAD语句
LOAD语句:利用MSSQL中的xp_cmdshell功能,将指定文件夹下的指定文件,生成mysql的LOAD语句 declare @sql varchar(4000), @dirpath varch ...
- [PHP]利用MetaWeblog API实现XMLRPC功能
[PHP]利用MetaWeblog API实现XMLRPC功能 | OWNSELF [PHP]利用MetaWeblog API实现XMLRPC功能 Windows Live Writer是一款小巧的写 ...
- Java单线程文件下载,支持断点续传功能
前言: 程序下载文件时,有时会因为各种各样的原因下载中断,对于小文件来说影响不大,可以快速重新下载,但是下载大文件时,就会耗费很长时间,所以断点续传功能对于大文件很有必要. 文件下载的断点续传: 1. ...
- 转:Http下载文件类 支技断点续传功能
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net ...
- java翻译到mono C#实现系列(4) 利用CountDownTimer类实现倒计时功能 mono版
群里的朋友问利用CountDownTimer类实现倒计时功能怎么实现,我就百度了,参考http://blog.csdn.net/qq344429461/article/details/7521361写 ...
- C#下利用正则表达式实现字符串搜索功能的方法(转)
关键字:正则表达式.元字符.字符串.匹配: 1.正则表达式简介:正则表达式提供了功能强大.灵活而又高效的方法来处:.NET框架正则表达式并入了其他正则表达式实现的: 2.字符串搜索:正则表达式语言由两 ...
随机推荐
- 来看看CBIS 2017中国(上海)大数据产业创新峰会有哪些大师出席
CBIS 2017中国(上海)大数据产业创新峰会,围绕"数据+产业.企业+数据.技术+人才.品牌+市场.应用+发展"相继展开话题讨论. CBIS 2017中国(上海)大数据产业创新 ...
- 浙大pat 1012题解
1012. The Best Rank (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue To eval ...
- 世界之窗(TheWorld)浏览器 3.6.1.0 简体中文绿色版
软件名称: 世界之窗(TheWorld)浏览器 3.6.1.0 简体中文绿色版软件语言: 简体中文授权方式: 免费软件运行环境: Win7 / Vista / Win2003 / WinXP 软件大小 ...
- Struts2中实现文件上传的功能
1.首先得配置一下Struts得配置文件struts-xml: <?xml version="1.0" encoding="UTF-8" ?> &l ...
- 12C RMAN 备份参考v1
windows bat 1,C:\dba\utility\rman\rman.bat del C:\dba\utility\rman\full_db_* /qset TNSNAME=ceipuatrm ...
- LWP::UserAgent介绍3 -> cookie设置
use LWP::UserAgent; use HTTP::Cookies; my $ua = LWP::UserAgent->new; $ua->cookie_jar(HTTP::Coo ...
- jquery学习笔记3 jq遍历
遍历方式:向上(父级元素) 向下(子元素) 水平(同胞元素) 一.向上遍历 parent() 向上一级 放回被选元素的直接父元素 parents() 返回被选元 ...
- 架设自己的FTP服务器 Serv-U详细配置图文教程
转自:http://www.jb51.net/article/31635.htm 所有不是很要求安全的情况下是可以用serv_U的,当然我们也可以通过一些设置,保证serv_u安全运行.这里就分享下s ...
- win10系统 L2TP连接尝试失败:ERROR因为安全层在初始化与远程计算机的协商时遇到了一个处理错误
1 确保IPsec Policy Agent服务已启动 2 确保路由和远程访问(Routing and Remote Access)和远程访问连接管理器服务(Remote Access Connect ...
- Jenkins中集成Gcov代码覆盖率报告
最近终于把gcov代码覆盖报告集成到jenkins中了,总算是完成工作,写篇博客总结下. 我循序渐进地用了三个工具:gcov, lcov, gcovr 这三个工具原理(其实gcovr依赖于GNU的gc ...