下载器

#import "ViewController.h"

@interface ViewController ()
{
    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

你可能感兴趣的:(下载器)