首先是业务中的.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完成的断点续传功能的更多相关文章

  1. 利用其它带文件防护功能的软件防止*.asp;*.jpg写入文件。

    此木马是一个.NET程序制作,如果你的服务器支持.NET那就要注意了,,进入木马有个功能叫:IIS Spy,点击以后可以看到所有站点所在的物理路径.以前有很多人提出过,但一直没有人给解决的答案.. 防 ...

  2. iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充

    一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...

  3. chrome断点续传功能

    刚好找到了一个临时的解决方法,chrome其实已经内部实现了断点续传功能,不过应该还没完善,所以要自己打开.方法:用chrome在地址栏输入chrome://flags用搜索找到resumption( ...

  4. [置顶] LOAD语句:利用MSSQL中的xp_cmdshell功能,将指定文件夹下的指定文件,生成mysql的LOAD语句

    LOAD语句:利用MSSQL中的xp_cmdshell功能,将指定文件夹下的指定文件,生成mysql的LOAD语句 declare @sql varchar(4000), @dirpath varch ...

  5. [PHP]利用MetaWeblog API实现XMLRPC功能

    [PHP]利用MetaWeblog API实现XMLRPC功能 | OWNSELF [PHP]利用MetaWeblog API实现XMLRPC功能 Windows Live Writer是一款小巧的写 ...

  6. Java单线程文件下载,支持断点续传功能

    前言: 程序下载文件时,有时会因为各种各样的原因下载中断,对于小文件来说影响不大,可以快速重新下载,但是下载大文件时,就会耗费很长时间,所以断点续传功能对于大文件很有必要. 文件下载的断点续传: 1. ...

  7. 转:Http下载文件类 支技断点续传功能

    using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net ...

  8. java翻译到mono C#实现系列(4) 利用CountDownTimer类实现倒计时功能 mono版

    群里的朋友问利用CountDownTimer类实现倒计时功能怎么实现,我就百度了,参考http://blog.csdn.net/qq344429461/article/details/7521361写 ...

  9. C#下利用正则表达式实现字符串搜索功能的方法(转)

    关键字:正则表达式.元字符.字符串.匹配: 1.正则表达式简介:正则表达式提供了功能强大.灵活而又高效的方法来处:.NET框架正则表达式并入了其他正则表达式实现的: 2.字符串搜索:正则表达式语言由两 ...

随机推荐

  1. Angular React 和 Vue的比较

    Angular(1&2),React,Vue对比 一 数据流 数据绑定 Angular 使用双向绑定即:界面的操作能实时反映到数据,数据的变更能实时展现到界面. 实现原理: $scope变量中 ...

  2. 初级AD域渗透系列

      net group /domain 获得所有域用户组列表 net group “domain admins” /domain 获得域管理员列表 net group “enterprise admi ...

  3. c3p0私有属性checkoutTimeout设置成1000引发的调试错误:

    checkoutTimeout设置成1000引发的调试错误: org.mybatis.spring.MyBatisSystemException: nested exception is org.ap ...

  4. HTML中判断手机是否安装某APP,跳转或下载该应用

    有些时候在做前端输出的时候,需要和app的做些对接工作.就是在手机浏览器中下载某app时,能判断该用户是否安装了该应用.如果安装了该应用,就直接打开该应用:如果没有安装该应用,就下载该应用.那么下面就 ...

  5. 二.创建maven工程及下载需要的jar包

    1.使用Eclipse的Maven插件来创建一简单的Maven项目 步骤:打开新建项目对话框,选择Maven Project(File->New->Object->Maven-> ...

  6. iOS 打包上传AppStore相关(3)-iTunes相应配置以及使用蒲公英网站进行应用托管分发(链接/二维码)

    上一篇讲到我们最终生成了一个格式为 .xcarchive 的文件(可以右键并Show in Finder)查看.本篇我们就进行最后的设置,打包上传.另外,还有一个小福利,那就是打测试包分发链接测试. ...

  7. QT自绘标题和边框

    在QT中如果想要自绘标题和边框,一般步骤是: 1) 在创建窗口前设置Qt::FramelessWindowHint标志,设置该标志后会创建一个无标题.无边框的窗口. 2)在客户区域的顶部创建一个自绘标 ...

  8. Weex-进阶笔记一

    p.p1 { margin: 0.0px 0.0px 2.0px 0.0px; font: 14.0px Helvetica; color: #454545 } p.p2 { margin: 0.0p ...

  9. PLSQL 几种游标的用法

    分类: Oracle 1. PL/SQL里的游标可以分为显式和隐式两种,而隐式有分为select into隐式游标和for .. in 隐式游标两种.所以,我们可以认为,有3种游标用法: A. 显式游 ...

  10. XAMPP 的MYSQL无法启动

    最近在学习小程序,小程序的后台cms系统需要安装XAMPP软件,这个软件是个集成软件,里面有MySql 和 Apache 等 ,首先进入小程序后台时需要启动MySql 和 Apache Apache ...