利用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.字符串搜索:正则表达式语言由两 ...
随机推荐
- js注入 mooc
javascript:(function(){try{var a=document.createElement('SCRIPT');a.type='text/javascript',a.src='// ...
- java 生成二维码
package com.sun.erwei; import java.awt.Graphics2D;import java.awt.geom.AffineTransform;import java.a ...
- 递归——CPS(二)
给出一个计算树深度的函数: function treeDepth(curtree) { if(curtree == null) return 0; else { var leftDepth = tre ...
- Abstraction elimination
(本文不保证不误人子弟,切勿轻信) Unlambda指的是lambda计算中去掉lambda操作(does not have lambda(or abstraction) operation of t ...
- [Q]关于无法进入主界面问题解答
打图精灵适用于AutoCAD2007或更高版,低于2007版无法使用. 若在安装打图精灵前AutoCAD已经打开,则需要将AutoCAD重新打开,然后使用“QPlot”命令. 若重新打开仍然调不出界面 ...
- [Q]升级/重新获取授权步骤
若因需要升级或授权文件失效(重装系统或其他原因),在服务期内可通过下面的步骤操作. 注:168元版提供2年升级及售后支持,118元版的提供1升级及售后支持. 步骤如下: 1. 重新获取CAD批量打图精 ...
- HihoCoder
#1043 : 完全背包 20160516 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说之前的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到 ...
- 《JavaScript DOM编程艺术》读书笔记
这是自己JS入门的一本书,反复看过几遍,作者的文笔风趣,阅读起来不枯燥也显轻松~ 本书从JS简史讲到基础语法到DOM,再以一个图片库案例为主线,讲如何运用JS来实现想要的动效,同时对已写案例进行兼容优 ...
- 1张图看懂RAID功能,6张图教会配置服务器【转】
RAID 包含一组或者一个集合甚至一个阵列.使用一组磁盘结合驱动器组成 RAID 阵列或 RAID 集.将至少两个磁盘连接到一个 RAID 控制器,而成为一个逻辑卷,也可以将多个驱动器放在一个组中.一 ...
- gvim窗口根据gnome-terminal位置定位
gvim启动位置固定的话容易挡到东西,所以写了一段vimscript根据gnome-terminal的位置启动gvim,这样被遮住的概率就一些了. fun! g:get_xterm_pos ()&qu ...