IOS AFNetWorking 下载文件 断点续传

最近在做视频音乐方面的东西,整理一下下载文件相关内容

功能需求:
             下载文件,可以显示进度,暂停,继续,断点续传

1、首先下载文件相关代码:有三个回调方法:下载进度,下载成功,下载失败
         要说明的是下载进度显示:在一个tableview中显示正在下载的文件,分为:1)存储下载文件信息(名字,图片链接,下载地址,文件格式,文件大小等)。2)实时更新进度条,我个人是创建了一个单例,存储下载地址和下载进度,key值为地址 ,value为进度;然后把多个键值对存到单例的数组中,然后在下载中心取出来,对cell单独进行更新

    NSFileManager *fileManager = [NSFileManager defaultManager];
    //检查本地文件是否已存在
    NSString *fileName = [NSString stringWithFormat:@"%@/%@.mp4", aSavePath, aFileName];

    //检查附件是否存在
    if ([fileManager fileExistsAtPath:fileName]) {
        NSData *audioData = [NSData dataWithContentsOfFile:fileName];
        [self showHoderTopView:@"已经加入您的缓存"];
        // [self requestFinished:[NSDictionary dictionaryWithObject:audioData forKey:@"res"] tag:aTag];
    }else{
        //创建附件存储目录
        if (![fileManager fileExistsAtPath:aSavePath]) {
            [fileManager createDirectoryAtPath:aSavePath withIntermediateDirectories:YES attributes:nil error:nil];
        }
        
        //下载附件
        NSURL *url = [[NSURL alloc] initWithString:aUrl];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

        operation.inputStream   = [NSInputStream inputStreamWithURL:url];
        operation.outputStream  = [NSOutputStream outputStreamToFileAtPath:fileName append:NO];
    
        //下载进度控制
        [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
            
            NSString *progress = [NSString stringWithFormat:@"%f",(float)totalBytesRead/totalBytesExpectedToRead];
            
        }];
        
        
        //已完成下载
        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
            [self showHoderTopView:@"缓存成功"];
            
            NSData *audioData = [NSData dataWithContentsOfFile:fileName];
            NSString *byte = [NSString stringWithFormat:@"%d",audioData.length];

            //设置下载数据到res字典对象中并用代理返回下载数据NSData
            // [self requestFinished:[NSDictionary dictionaryWithObject:audioData forKey:@"res"] tag:aTag];
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            
            //下载失败
            //[self requestFailed:aTag];
        }];
        [operation start];

2、暂停和继续和取消

       AFHTTPRequestOperation对象方法分别对应 pause  resume  cancel 。问题在于怎么获取到这个对象,我用的方法比较粗糙,就是存储了这个对象到刚才的单例中,关键字也是下载链接,只要这个对象存活就能拿到并进行操作。如果对象不存在又要继续刚才的任务,接下来就是断点续传了


3、断点续传

找了很多有关断点续传的资料,这篇博客的简单实用

来自CSDN博客:AFNetworking实现程序重新启动时的断点续传 http://blog.csdn.net/zhaoxy2850/article/details/21383515

//获取已下载的文件大小
- (unsigned long long)fileSizeForPath:(NSString *)path {
    signed long long fileSize = 0;
    NSFileManager *fileManager = [NSFileManager new]; // default is not thread safe
    if ([fileManager fileExistsAtPath:path]) {
        NSError *error = nil;
        NSDictionary *fileDict = [fileManager attributesOfItemAtPath:path error:&error];
        if (!error && fileDict) {
            fileSize = [fileDict fileSize];
        }
    }
    return fileSize;
}
//开始下载
- (void)startDownload {
    NSString *downloadUrl = @"http://www.xxx.com/xxx.zip";
    NSString *cacheDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *downloadPath = [cacheDirectory stringByAppendingPathComponent:@"xxx.zip"];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:downloadUrl]];
    //检查文件是否已经下载了一部分
    unsigned long long downloadedBytes = 0;
    if ([[NSFileManager defaultManager] fileExistsAtPath:downloadPath]) {
	//获取已下载的文件长度
        downloadedBytes = [self fileSizeForPath:downloadPath];
        if (downloadedBytes > 0) {
            NSMutableURLRequest *mutableURLRequest = [request mutableCopy];
            NSString *requestRange = [NSString stringWithFormat:@"bytes=%llu-", downloadedBytes];
            [mutableURLRequest setValue:requestRange forHTTPHeaderField:@"Range"];
            request = mutableURLRequest;
        }
    }
    //不使用缓存,避免断点续传出现问题
    [[NSURLCache sharedURLCache] removeCachedResponseForRequest:request];
    //下载请求
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    //下载路径
    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:downloadPath append:YES];
    //下载进度回调
    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        //下载进度
        float progress = ((float)totalBytesRead + downloadedBytes) / (totalBytesExpectedToRead + downloadedBytes);
    }];
    //成功和失败回调
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
            
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            
    }];
    [operation start];
}

       

你可能感兴趣的:(ios开发进阶)