#import "ViewController.h"
@interface ViewController ()<NSURLConnectionDataDelegate>
@property (nonatomic,strong) UIProgressView *progressView;
@property (nonatomic,strong) UILabel *progressLabel;
@property (nonatomic,strong) UIButton *startButton;
@property (nonatomic,strong) UIButton *stopButton;
//临时文件,存储当前下载多少数据
@property (nonatomic,copy) NSString *tempFilePath;
//更新文件数据的助手
@property (nonatomic,strong) NSFileHandle *fileHand;
//记录临时文件的数据大小
@property (nonatomic,assign) unsigned long long tempFileSize;
//记录总数据的大小
@property (nonatomic,assign) unsigned long long fullFileSize;
//记录当前数据的大小
@property (nonatomic,assign) unsigned long long currentSize;
//定义链接属性
@property (nonatomic,strong) NSURLConnection *connection;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self createUI];
//创建临时文件,存储下载了多少数据
self.tempFilePath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"tempFile"];
//获得文件的大小
NSDictionary *infoDic = [[NSFileManager defaultManager] attributesOfItemAtPath:self.tempFilePath error:nil];
self.tempFileSize = [infoDic[NSFileSize] integerValue];
//为当前数据大小赋值
self.currentSize = self.tempFileSize;
//取一下本地得总长度
NSNumber *fullSizeNumber = [[NSUserDefaults standardUserDefaults] objectForKey:@"currentSize"];
self.fullFileSize = [fullSizeNumber unsignedLongLongValue];
//kvo检测当前数据进度
[self addObserver:self forKeyPath:@"currentSize" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"currentSize"]) {
NSNumber *newNumber = change[@"new"];
//获得新值的大小
unsigned long long newSize = [newNumber unsignedLongLongValue];
//计算当前进度比
float p = 0;
if (self.fullFileSize != 0) {
p = newSize *1.0 / self.fullFileSize;
self.progressView.progress = p;
self.progressLabel.text = [NSString stringWithFormat:@"%.2f%%",p*100];
}
}
}
- (void)createUI{
self.progressLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width,20)];
self.progressLabel.text = @"0%";
self.progressLabel.backgroundColor = [UIColor lightGrayColor];
self.progressLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.progressLabel];
self.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(10, 50, self.view.bounds.size.width - 20, 20)];
[self.view addSubview:self.progressView];
self.startButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.startButton.frame = CGRectMake(50, 80, 60, 20);
[self.startButton setTitle:@"开始" forState:UIControlStateNormal];
[self.startButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
self.startButton.tag = 10;
[self.startButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.startButton];
self.stopButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.stopButton.frame = CGRectMake(200, 80, 60, 20);
[self.stopButton setTitle:@"停止" forState:UIControlStateNormal];
[self.stopButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
self.stopButton.tag = 11;
[self.stopButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.stopButton];
}
- (void)buttonClicked:(UIButton *)button{
if (button.tag == 10) {
//开始下载之后让按钮禁止被点击
self.startButton.enabled = NO;
//开始下载
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://dldir1.qq.com/qqfile/QQforMac/QQ_V4.0.2.dmg"]];
//中断下载之后重新开始下载需告知服务器从那一段开始返回数据
//判断临时文件是否存在 存在的话将文件大小与请求头中告知服务器这段数据无需在下载
NSFileManager *fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath:self.tempFilePath]) {
NSString *bytesValue = [NSString stringWithFormat:@"bytes=%lld-",self.tempFileSize];
//设置请求头
[request setValue:bytesValue forHTTPHeaderField:@"RANGE"];
}
//创建连接发起请求
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
}else{
//停止下载
//停止请求
[self.connection cancel];
if (self.startButton.enabled == NO) {
self.startButton.enabled = YES;
}
}
}
#pragma mark -协议方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
//获得响应头信息,使用nshttpurlresponse强转
NSDictionary *responseHeaders = [(NSHTTPURLResponse *)response allHeaderFields];
//获得文件的数据大小
unsigned long long contentLength = [responseHeaders[@"Content-Length"] integerValue];
//获得临时文件判断临时文件是否存在,不存在就创建
NSFileManager *manager = [NSFileManager defaultManager];
if (![manager fileExistsAtPath:self.tempFilePath]) {
[manager createFileAtPath:self.tempFilePath contents:nil attributes:nil];
//给记录总长度数据的参数赋值
self.fullFileSize = contentLength;
}else{
self.fullFileSize = self.tempFileSize + contentLength;
self.currentSize = self.tempFileSize;
}
//将总数据长度存储于本地
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@(self.fullFileSize) forKey:@"fullSize"];
[userDefaults synchronize];
//创建一个更新的fileHandle来时刻更新文件的大小
self.fileHand = [NSFileHandle fileHandleForUpdatingAtPath:self.tempFilePath];
[self.fileHand seekToEndOfFile];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
self.currentSize += data.length;
[self.fileHand writeData:data];
//找到文件所有属性
NSDictionary *infoDic = [[NSFileManager defaultManager] attributesOfItemAtPath:self.tempFilePath error:nil];
//获得文件大小
self.tempFileSize = [infoDic[NSFileSize] integerValue];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
//下载完成
//关闭文件
[self.fileHand closeFile];
//开启开始按钮的使用状态
self.startButton.enabled = YES;
//移动到桌面
NSFileManager *fm = [NSFileManager defaultManager];
NSString *toPath = @"/Users/fudong/Desktop/QQ.dmg";
//移动
[fm moveItemAtPath:self.tempFilePath toPath:toPath error:nil];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
//请求失败
[self.fileHand closeFile];
self.startButton.enabled = YES;
}
- (void)dealloc
{
[self removeObserver:self forKeyPath:@"currentSize"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
本文介绍了一种基于iOS系统的智能下载应用,通过实现文件下载、进度显示、暂停和继续功能,提升用户下载体验。

868

被折叠的 条评论
为什么被折叠?



