首先是业务中的.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. ES 6 : let与const

    1.let命令 [ 基本用法 ] let命令的用法与var类似,用于声明一个变量,但是let声明的变量只能在let所在的代码块内有效: 上述代码块中使用let和var声明了两个变量.然后在代码块之外调 ...

  2. MongoDB1: 环境安装

    1. 环境准备,不支持XP系统,需要在Windows7及以上和windows server 2008 系统上安装. 2. 下载安装包:http://www.mongodb.org/downloads, ...

  3. C# Oracle insert 中文乱码

    问题描述: 在PL SQL中insert 中文数据,显示不乱码,通过后台insert的中文数据,显示问号. 解决分三步: 1.Select userenv('language') from dual; ...

  4. SAP HANA创建层次结构的属性视图(Hierarchy Attribute View)

    在产品表中,数据是具有一定层次结构的 1. 在Content相应的package下面右键点击Attribute View,新建Attribute View 填写相关信息,注意:我们所建的依然是标准视图 ...

  5. UltraISO PE(软碟通) V9.5.5.2960 官方中文版

    软件名称: UltraISO PE(软碟通)软件语言: 简体中文授权方式: 免费试用运行环境: Win7 / Vista / Win2003 / WinXP 软件大小: 1.9MB图片预览: 软件简介 ...

  6. php的redis的pconnect

    1. 当使用pconnect时,连接会被重用,连接的生命周期是fpm进程的生命周期,而非一次php的执行. 2.如果代码中使用pconnect, close的作用仅是使当前php不能再进行redis请 ...

  7. Codeforces Round #346 (Div. 2) B Qualifying Contest

    B. Qualifying Contest 题目链接http://codeforces.com/contest/659/problem/B Description Very soon Berland ...

  8. OpenCV FileStorage 使用记录

    FileStorage OpenCV 中的 FileStorage 类能够读写硬盘中的.xml和.yaml文件,这里我们只讨论对 .xml 的以下几种操作: 写入(FileStorage::WRITE ...

  9. Managed Switch: Confs

    shortcuts: c-w: delete word before c-a: move to first char c-y: delete everything after cursor c-z: ...

  10. redis 5 种数据结构

    常用命令 就DB来说,Redis成绩已经很惊人了,且不说memcachedb和tokyocabinet之流,就说原版的memcached,速度似乎也只能达到这个级别.Redis根本是使用内存存储,持久 ...