下载器

作者: Dove_Q | 来源:发表于2016-10-08 08:54 被阅读35次
#import "ViewController.h"

@interface ViewController ()<NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
{
    UITextField *_textfield;
    UIProgressView *_progressView;
    NSURLSession *_session;
    NSURLSessionDataTask *_task;
    NSMutableData *_data;
    NSInteger _sourceSize;
    NSFileHandle *_writeHandle;
    NSString *_api;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor grayColor];
    [self creatLayout];
    
//    图片: http://i2.cqnews.net/car/attachement/jpg/site82/20120817/5404a6b61e3c1197fb211d.jpg
//    音乐: http://link.hhtjim.com/163/422104315.mp3
//    视频: http://data.vod.itc.cn/?rb=1&prot=1&key=jbZhEJhlqlUN-Wj_HEI8BjaVqKNFvDrn&prod=flash&pt=1&new=/198/232/8mIXFONKIQNHKlScaM76kB.mp4
    _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
#pragma mark 创建布局
- (void)creatLayout {
    _textfield = [UITextField new];
    _textfield.backgroundColor = [UIColor whiteColor];
    _textfield.frame = CGRectMake(50, 150, 300, 50);
    [self.view addSubview:_textfield];
    
    UIButton *startButton = [UIButton buttonWithType:UIButtonTypeSystem];
    startButton.frame = CGRectMake(50, 250, 80, 50);
    [startButton setTintColor:[UIColor whiteColor]];
    startButton.backgroundColor = [UIColor redColor];
    [startButton setTitle:@"开始" forState:UIControlStateNormal];
    [startButton addTarget:self action:@selector(didClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:startButton];
    
    UIButton *pauseButton = [UIButton buttonWithType:UIButtonTypeSystem];
    pauseButton.frame = CGRectMake(270, 250, 80, 50);
    [pauseButton setTintColor:[UIColor whiteColor]];
    pauseButton.backgroundColor = [UIColor redColor];
    [pauseButton setTitle:@"暂停" forState:UIControlStateNormal];
    [pauseButton addTarget:self action:@selector(didClicked:)forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:pauseButton];
    
    _progressView = [UIProgressView new];
    _progressView.frame = CGRectMake(50, 350, 300, 50);
    [self.view addSubview:_progressView];
}
#pragma mark 点击Button
- (void)didClicked: (UIButton *)sender {
    if ([sender.currentTitle isEqualToString:@"开始"]) {
        _api = _textfield.text;
        NSLog(@"API: %@", _api);
        NSString *targetFileName = [self cacheNameWithURL:_api];
        //缓存文件不存在
        if (![[NSFileManager defaultManager] fileExistsAtPath:targetFileName]) {
            //完整文件存在
            if ([[NSFileManager defaultManager] fileExistsAtPath:[self fileNameWithURL:_api]]) {
                UIAlertController *alertCtl = [UIAlertController alertControllerWithTitle:@"文件已存在" message:@"是否重新下载" preferredStyle:UIAlertControllerStyleAlert];
                UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"是" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                    //删除文件, 重新创建文件且重新启动任务
                    [[NSFileManager defaultManager] removeItemAtPath:[self fileNameWithURL:_api] error:nil];
                    [[NSFileManager defaultManager] createFileAtPath:targetFileName contents:nil attributes:nil];
                    _writeHandle = [NSFileHandle fileHandleForWritingAtPath:targetFileName];
                    _task = [_session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:_api]]];
                    [_task resume];
                }];
                UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"否" style:UIAlertActionStyleDestructive handler: nil];
                [alertCtl addAction:action2];
                [alertCtl addAction:action1];
                [self presentViewController:alertCtl animated:YES completion:nil];
            }
            //只有缓存文件存在
            else {
                [[NSFileManager defaultManager] createFileAtPath:targetFileName contents:nil attributes:nil];
                _writeHandle = [NSFileHandle fileHandleForWritingAtPath:targetFileName];
                _task = [_session dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:_api]]];
                [_task resume];
            }
        }
        //缓存文件存在
        else {
            _writeHandle = [NSFileHandle fileHandleForWritingAtPath:targetFileName];
            [_writeHandle seekToEndOfFile];
            
            //如果暂停
            if (_task.state == NSURLSessionTaskStateSuspended) {
                [_task resume];
                NSLog(@"开始");
            }
            //已经结束, 重新启动任务
            else {
                if (!_api.length) {
                    return;
                }
                NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:[self cacheNameWithURL:_api]];
                //获取未完成的缓存文件大小
                NSLog(@"缓存文件大小: %lld", [readHandle seekToEndOfFile]);
                NSMutableURLRequest *mutiRequest= [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_api]];
                //自定义下载范围("bytes=100-":表示下载100以后的所有数据, "bytes=-100":表示下载0~100的数据),Key必须是"Range"
                //注意自己设置过"request"以后,状态码"statusCode"会变成"206"
                [mutiRequest setValue:[NSString stringWithFormat:@"bytes=%lld-", [readHandle seekToEndOfFile]] forHTTPHeaderField:@"Range"];
                _task = [_session dataTaskWithRequest:mutiRequest];
                [_task resume];
            }
        }
    }
    //暂停
    else {
        if (_task.state == NSURLSessionTaskStateRunning) {
            [_task suspend];
            NSLog(@"暂停");
        }
    }
}
#pragma mark 响应
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    
    NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
    _sourceSize = resp.expectedContentLength;
    NSLog(@"%ld", _sourceSize);
    NSLog(@"%@", resp);
    _data = [NSMutableData data];
    _progressView.progress = 0;
    if (resp.statusCode == 200 || resp.statusCode == 206) {
        completionHandler(NSURLSessionResponseAllow);
    }
}
#pragma mark 数据
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    NSLog(@"%ld", data.length);
    [_data appendData:data];
    _progressView.progress = (float)_data.length / _sourceSize;
    [_writeHandle writeData:data];
}
#pragma mark 下载完成
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    if (!error) {
        NSLog(@"完成");
        [[NSFileManager defaultManager] moveItemAtPath:[self cacheNameWithURL:_api] toPath:[self fileNameWithURL:_api] error:nil];
    }
    else {
        NSLog(@"error: %@", error);
    }
    [_writeHandle closeFile];
}
#pragma mark 获取文件名
- (NSString *)fileNameWithURL:(NSString *)URLName {
    if (!URLName) {
        return nil;
    }
    NSArray *tempArray = [URLName componentsSeparatedByString:@"/"];
    NSString *tempPath = tempArray.lastObject;
    NSString *fileName = [NSString stringWithFormat:@"%@/%@", @"Users/apple/Desktop", tempPath];
    return fileName;
}
#pragma mark 获取缓存文件名
- (NSString *)cacheNameWithURL:(NSString *)URLName {
    if (!URLName) {
        return nil;
    }
    NSArray *urlArray = [URLName componentsSeparatedByString:@"/"];
    NSString *fileName = urlArray.lastObject;
    NSArray *tempArray = [fileName componentsSeparatedByString:@"."];
    NSString *tempStr = tempArray.firstObject;
    NSString *cacheName = [tempStr stringByAppendingString:@".cache"];
    NSString *cacheFileName = [NSString stringWithFormat:@"%@/%@", @"/Users/apple/Desktop", cacheName];
    return cacheFileName;
}

@end

相关文章

  • YK设计思路

    下载器->启动器->客户端. 0.下载下载器,然后放置在C,启动下载器1.下载器下载启动器。然后放置在C,启动启动...

  • 下载器

    因为是学中文的,所以就很敏感,第一眼看到就觉得这四个字不对劲。”日前,在重庆大学中文系读大三的小赵和朋友在沙坪坝三...

  • 下载器

  • 下载器

    AVRISP mkII下载器两台,分了两个供应商采购,结果真的不同,是我预料之外的,刚好满足我们输入同系列两个不同...

  • iOS 下载管理器

    iOS 下载管理器 iOS 下载管理器

  • Python爬虫-scrapy介绍及使用

    scrapy的流程 其流程可以描述如下: ● 调度器把requests–>引擎–>下载中间件—>下载器 ● 下载器...

  • Ubuntu 14.04.5 安装mongo

    1、安装包下载 mongodb官方下载地址 手动下载移植到服务器或者再服务器直接下载 服务器直接下载:curl ...

  • 关于Chrome浏览器启动页被劫持和篡改的解决办法

    在一些软件下载平台下载软件的时候会首先下载一个下载器,然后通过下载器才能下载到想要的软件,坑爹的是这个下载器会自动...

  • Selenium+WebDriver、Selenium+Grid

    一.下载浏览器驱动 查看自己的浏览器版本,下载浏览器驱动 1.谷歌浏览器驱动下载http://chromedriv...

  • 2018-08-19「插件」Chrono下载管理器

    Chrono下载管理器 做Chrome浏览器中最好的下载管理器 Chrono下载管理器是Chrome浏览器下第一款...

网友评论

      本文标题:下载器

      本文链接:https://www.haomeiwen.com/subject/quluyttx.html