利用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.字符串搜索:正则表达式语言由两 ...
随机推荐
- [ mysql优化一 ] explain解释select语句
NOSQL 没有什么数据表, 只是一些变量,key_value ,redis 支持的变量比较多.可以持久化文件到硬盘上. mysql 关系型数据库 ,表和表中间有各种id的关系. 缺点 高并发读 ...
- C# 语言规范_版本5.0 (第8章 语句)
1. 语句 C# 提供各种语句.使用过 C 和 C++ 编程的开发人员熟悉其中大多数语句. statement: labeled-statement declaration-statement emb ...
- Windows Server2012上使用Nginx做文件服务器
由于项目中用到了大量的文件上传和删除,考虑到安全的因素,所以整体的思路是使用FTP从主服务器把文件资源上传到文件服务器上. FTP上传到服务器的代码如下(简单附加一下,具体的网上很多) public ...
- 为什么要html语义化?
1.什么是HTML语义化? <基本上都是围绕着几个主要的标签,像标题(H1~H6).列表(li).强调(strong em)等等> 根据内容的结构化(内容语义化),选择合适的标签(代码语义 ...
- winsock编程IOCP模型实现代码
winsock编程IOCP模型实现代码 话不多说,上代码.借鉴<windows核心编程>部分源码和CSDN小猪部分代码. stdafx.h依赖头文件: #include <iostr ...
- servlet的url-pattern匹配规则
首先需要明确几容易混淆的规则: servlet容器中的匹配规则既不是简单的通配,也不是正则表达式,而是特定的规则.所以不要用通配符或者正则表达式的匹配规则来看待servlet的url-pattern. ...
- Android系统签名文件
系统签名所需要的工具 signapk.jar -------------------->out/host/linux-x86/framework/signapk.jar (build/tools ...
- weex 语法高亮
@1.ctrl+shift+p,调出控制命令面板,@2.输入pic,点击进入 @3.输入vue Syntax Highlight,等待下载 所有的sublime下载插件同理. vue Syntax H ...
- 微信小程序学习总结(1)
1.一个小程序文件最基本包含app.js.app.json.app.wxss和pages文件夹结构,pages中的页面必须要在app.json的pages项进行配置,app.json也提供窗口表现,t ...
- java复习 --集合类
List接口:可以存放重复内容: set接口:不能存放重复内容,重复内容依靠hashcode和equal两个方法来区分: Queue:队列: SortedSet接口:对集合中的数据进行排序: Li ...