iOS断点续传

本文介绍了一种基于iOS系统的智能下载应用,通过实现文件下载、进度显示、暂停和继续功能,提升用户下载体验。

#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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值