关键词:
【中文标题】使用 AFNetworking 计算下载多个文件的总进度【英文标题】:calculating total progress of downloading multiple file with AFNetworking 【发布时间】:2014-09-07 13:57:16 【问题描述】:我想下载多个文件,然后向用户显示总进度。
但问题就在这里,我不知道我应该如何计算总进度。
这是我的工作: 首先我得到了预计从所有文件中接收的总字节数:
for (NSURL candidateUrl in UrlsList)
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:candidateURL];
//setting HTTPMethod of request from GET to HEAD to download header files of requests, so we can get file size before downloaing file
[request setHTTPMethod:@"HEAD"];
getTotalImagesBytesOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[getTotalImagesBytesOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
//setting totalImagesBytesExpectedToRead of all images. we use it to know how many bytes we should download for all the images
totalImagesBytesExpectedToRead += [operation.response expectedContentLength];
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Error: %@", error);
];
[operationQueue addOperation:getTotalImagesBytesOperation];
估计总文件大小后:
//downloading images
for (NSURL *imageUrl in imagesURLList)
NSURLRequest *request = [NSURLRequest requestWithURL:imageUrl];
AFImageRequestOperation *downloadImageOperation = [AFImageRequestOperation imageRequestOperationWithRequest:request
imageProcessingBlock:nil
success: ^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image)
NSLog(@"success")
failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error)
NSLog(@"%@", [error localizedDescription]);
];
[operationQueue addOperation:downloadImageOperation];
[downloadImageOperation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
**HOW TO CALCULATE TOTAL PROGRESS**
我不知道如何计算总大小! 我们拥有的价值观: 以上方法为您提供的当前文件的 totalBytesOfAllTheFiles、totalBytesRead 和 totalBytesExpectedToRead、indexOfCurrentFile 和 countOfFiles。
小心 setDownloadProgressBlock 调用数百次。
有人知道吗? (抱歉代码格式错误!)
【问题讨论】:
你不把totalBytesRead
除以totalBytesExpectedToRead
吗?
@evan.stoddard totalBytesRead/totalBytesExpectedToRead
给了我当前文件的完成百分比。不是整个文件!
首先考虑:你真的需要如此精确才能使用总字节数来计算进度吗?我使用“下载的总文件数”/“要下载的总文件数”来计算应用程序的进度。这要容易得多。
想一想您的前五个文件的总大小为 1 mb,而后五个文件的大小为 100 mb。这个计算不好。
在这种情况下,唯一的方法可能是在下载开始之前从网络某处的数据文件中读取“总大小”信息。如果这不可能,您必须重新考虑您的应用程序设计。在下载文件之前,您无法知道所有文件的大小。
【参考方案1】:
我是这样实现的: 首先创建一个NSOperationQueue:
// Add the operation to a queue
// It will start once added
//calculating images byte size
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue setMaxConcurrentOperationCount:1];
foreach (NSURL *candidateURL in urlList )
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:candidateURL];
//setting HTTPMethod of request from GET to HEAD to download header files of requests, so we can get file size before downloaing file
[request setHTTPMethod:@"HEAD"];
AFHTTPRequestOperation *getTotalImagesBytesOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[getTotalImagesBytesOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
//setting totalImagesBytesExpectedToRead of all images. we use it to know how many bytes we should download for all the images
totalImagesBytesExpectedToRead += [operation.response expectedContentLength];
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Error: %@", error);
];
[operationQueue addOperation:getTotalImagesBytesOperation];
//downloading images which should be downloaded
for (NSURL *imageUrl in imagesShouldBeDownlaoded)
NSURLRequest *request = [NSURLRequest requestWithURL:imageUrl];
AFHTTPRequestOperation *downloadFileOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
//we must provide file path with file name and its extension
NSString *fileName = [self getImageName:[imageUrl absoluteString]];
downloadFileOperation.outputStream = [NSOutputStream outputStreamToFileAtPath:[[ImageManager applicationDocumentsDirectory] stringByAppendingPathComponent:fileName] append:NO];
[downloadFileOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation , id response)
NSLog(@"file saved");
failure:^(AFHTTPRequestOperation *operation, NSError *error)
completionBlock(NO, error);
NSLog(@"%@", [error localizedDescription]);
];
[operationQueue addOperation:downloadFileOperation];
[downloadFileOperation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
totalBytesDownloaded += bytesRead;
//total progress from 0.0 to 1.0
progress = ((float)totalBytesDownloaded/(float)totalImagesBytesExpectedToRead);
if(progress == 1)
completionBlock(YES, nil);
progressCallback(progress);
];
operationQueue 作为一个 FIFO 列表,首先计算图像字节大小,然后开始下载所有图像
【讨论】:
请解释一下completionBlock和progressCallback的使用。另外,您从哪里开始操作,例如 [downloadFileOperation Start]。请发表评论。我有点卡在这里。 不需要显式启动操作,下载操作会通过添加操作到操作队列中隐式启动。另外,completionBlock 和 progressCallback 是我的自定义块,它们会通知我下载进度或下载失败或成功。【参考方案2】:AFNetworking3 使用dispatch_group
和NSProgress
来实现:
#import <Foundation/Foundation.h>
#import <AFNetworking.h>
@interface Server : NSObject
@property (nonatomic, strong) AFHTTPSessionManager *manager;
@property (nonatomic, strong) NSProgress *progress;
- (void)downloadFilesWithUrls:(NSMutableArray <NSURL *>*)urls;
@end
#import "Server.h"
@implementation Server
- (instancetype)init
self = [super init];
if (self)
_manager = [AFHTTPSessionManager manager];
_manager.requestSerializer = [AFJSONRequestSerializer serializer];
_manager.responseSerializer = [AFJSONResponseSerializer serializer];
_progress = [NSProgress progressWithTotalUnitCount:0];
[_progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:nil];
return self;
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
NSLog(@"fractionCompleted:%lf",self.progress.fractionCompleted);
- (void)downloadFilesWithUrls:(NSMutableArray <NSURL *>*)urls
//progress
dispatch_group_t group = dispatch_group_create();
_progress.totalUnitCount = urls.count;
[urls enumerateObjectsUsingBlock:^(NSURL * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)
dispatch_group_enter(group);
NSURLRequest *request = [NSURLRequest requestWithURL:obj];
NSURLSessionDownloadTask *task = [self.manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress)
destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response)
return [[[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil] URLByAppendingPathComponent:[response suggestedFilename]];
completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error)
NSLog(@"one task completion");
dispatch_group_leave(group);
];
NSProgress *child = [self.manager downloadProgressForTask:task];
[self.progress addChild:child withPendingUnitCount:1];
[task resume];
];
dispatch_group_notify(group, dispatch_get_main_queue(), ^
NSLog(@"%lf", self.progress.fractionCompleted);
);
@end
【讨论】:
AFNetworking/NSURLSession耗时长创建100多个任务下载文件
】AFNetworking/NSURLSession耗时长创建100多个任务下载文件【英文标题】:AFNetworking/NSURLSessiontakeslongtocreatemorethan100taskstodownloadfiles【发布时间】:2017-08-1115:15:40【问题描述】:我的应用程序需要下载许多文件,我使用for循环来创建下... 查看详情
AFNetworking 无法在 ios iPad 中下载多个 m4a 文件
】AFNetworking无法在iosiPad中下载多个m4a文件【英文标题】:AFNetworkingunabletodownloadmultiplem4afilesiniosiPad【发布时间】:2012-07-2316:30:01【问题描述】:我有一个从服务器下载音乐文件m4a的iPad应用程序。我正在使用AFHTTPRequestOperation直接... 查看详情
使用 AFNetworking 上传多个图像或文件,
】使用AFNetworking上传多个图像或文件,【英文标题】:UploadmultipleImageorFileusingAFNetworking,【发布时间】:2018-08-0611:31:04【问题描述】:我想使用AFNetworking上传多张图片。像这样PleaseCheckThisImage我附上了邮递员的例子。我的代码:NSS... 查看详情
使用 AFDownloadRequestOperation 下载队列中的多个文件
...8-1210:47:56【问题描述】:我正在使用AFDownloadRequestOperation+AFNetworking从服务器下载和恢复文件列表。该代码非常适合一次下载和恢复多个文件。但是如何在一个 查看详情
使用 AFNetworking 下载文件
】使用AFNetworking下载文件【英文标题】:DownloadingaFilewithAFNetworking【发布时间】:2013-10-1113:24:16【问题描述】:尝试为我的iPhone程序编写一个方法,该方法为文件提供URL地址,它将下载到iOS应用程序的文档目录。按照AFNetowrking的... 查看详情
如何使用 AFNetworking 上传多个文件
】如何使用AFNetworking上传多个文件【英文标题】:HowdoyouuploadmultiplefileswithAFNetworking【发布时间】:2012-03-0421:42:26【问题描述】:我可以毫无问题地上传单个文件,但现在我发现我需要上传1个或多个文件,有人知道如何使用AFNetwo... 查看详情
使用 AFNetworking 下载大文件
】使用AFNetworking下载大文件【英文标题】:DownloadinglargefileswithAFNetworking【发布时间】:2012-11-0308:14:14【问题描述】:我正在尝试实现大文件的下载并向用户显示当前进度,但阻止:-[AFURLConnectionOperationsetDownloadProgressBlock:]返回不... 查看详情
AFNetworking 下载的文件丢失
】AFNetworking下载的文件丢失【英文标题】:AFNetworkingdownloadedfilemissing【发布时间】:2016-03-0402:47:56【问题描述】:我正在使用AFNetworking3.0下载文件,下载部分似乎正常,但之后我找不到文件。我正在使用下面的代码。在下载任务... 查看详情
使用 afnetworking 一次下载一个文件
】使用afnetworking一次下载一个文件【英文标题】:Downloadonefileatatimeusingafnetworking【发布时间】:2016-06-2110:01:00【问题描述】:我有一个array,其中包含不同的URL。我想下载一个带有进度条的文件,然后开始下一个文件,依此类推... 查看详情
使用 AFNetworking 2.0 下载 PDF 文件
】使用AFNetworking2.0下载PDF文件【英文标题】:DownloadPDFfilewithAFNetworking2.0【发布时间】:2013-11-0221:06:33【问题描述】:我想更新到最新版本的AFNetworking。我想知道如何从服务器下载PDF以在我的应用程序中显示它。在旧版本上我使... 查看详情
下载许多文件时 AFNetworking / NSURLSession 超时
】下载许多文件时AFNetworking/NSURLSession超时【英文标题】:AFNetworking/NSURLSessiontimeoutswhendownloadingmanyfiles【发布时间】:2016-05-1909:26:54【问题描述】:在我的应用中,用户可以一次下载多个文件。这些文件每个大约2MB。由于用户可... 查看详情
afnetworking 多文件上传
】afnetworking多文件上传【英文标题】:afnetworkingmultiplefileupload【发布时间】:2012-12-1704:01:26【问题描述】:我正在使用AFNetworking上传多个文件。我需要为每个图像发送额外的信息,例如图像宽度/高度。我以为我会遍历图像并发... 查看详情
AFNetworking - 在恢复下载文件之前检查下载的字节?
】AFNetworking-在恢复下载文件之前检查下载的字节?【英文标题】:AFNetworking-CheckDownloadedbytesbeforeresumingdownloadingofthefile?【发布时间】:2013-06-0612:56:56【问题描述】:我正在使用AFDownloadRequestOperation通过AFNetworkingFramework下载文件,... 查看详情
AFNetworking:我需要自己删除下载的文件吗?
】AFNetworking:我需要自己删除下载的文件吗?【英文标题】:AFNetworking:DoIneedtodeletedownloadedfilemyself?【发布时间】:2015-12-1819:50:12【问题描述】:我正在使用AFNetworking下载一个zip文件。完成后调用此块。-(void)setDownloadTaskDidFinishDown... 查看详情
如何使用 AFNetworking 2.0 下载文件
】如何使用AFNetworking2.0下载文件【英文标题】:HowdodownloadafilewithAFNetworking2.0【发布时间】:2013-11-2306:10:33【问题描述】:我很难筛选搜索结果以了解如何执行此操作,并且在文档中找不到任何具体内容。我只想下载一个文件并... 查看详情
如何在 AFNetworking 2 中使用 POST + 参数下载经过身份验证的文件?
】如何在AFNetworking2中使用POST+参数下载经过身份验证的文件?【英文标题】:HowdownloadaauthenticatedfilewithaPOST+paramsinAFNetworking2?【发布时间】:2014-01-1322:45:49【问题描述】:我需要下载经过身份验证的文件。我在python端有这个:@api_... 查看详情
为多个文件下载添加子进度
...】:2016-02-0704:47:51【问题描述】:我正在我的项目中使用AFNetworking3.0下载多个文件。我想显示所有文件的单个下载进度。我将每个文件下载的每个子进度添加到父进度中。但它不起作用,应用程序崩溃了。我收到了错误-Terminating... 查看详情
使用 AFNetworking 解析 JSON 文件
】使用AFNetworking解析JSON文件【英文标题】:ParseJSONfileusingAFNetworking【发布时间】:2015-07-2709:06:14【问题描述】:我有一个包含json文件的链接。我的意思是,如果我在chrome中启动该链接,则会在我的计算机上下载一个扩展名为.jso... 查看详情