NSURLSession 下载任务 - 进度条问题

     2023-03-12     281

关键词:

【中文标题】NSURLSession 下载任务 - 进度条问题【英文标题】:NSURLSession Download Task- Progress Bar Issue 【发布时间】:2016-05-04 06:14:40 【问题描述】:

我正在处理一个非 ARC 项目,我必须在其中下载视频,下载后我将显示它们。我正在使用 NSURLSession 下载它。

问题在进度条中。当我开始下载第四个文件时,我可以通过进度条正确下载前两个或三个文件,进度条没有正确更新,但文件与最后删除的文件一起下载。

再次删除并再次下载时会崩溃

尝试在已失效的会话中创建任务

 - (void)startOrPauseDownloadingSingleFile : (UIButton *)sender
  
    self.part_id_Value = self.part_id;
    m_Web getIconPathForAnimation:self.part_id];

     [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
      NSURL *urlVideo=[NSURL URLWithString:self.NonInteractiveMP4URL];
      NSString *strlastcomponent=[urlVideo lastPathComponent];


      FileDownloadInfo *fdi = [[FileDownloadInfo alloc] initWithFileTitle:strlastcomponent andDownloadSource:[NSString stringWithFormat:@"%@",urlVideo]];



        if (!fdi.isDownloading)
        
            // Check if should create a new download task using a URL, or using resume data.


            if (fdi.taskIdentifier == -1)
            
             **Getting Crash Here**

                fdi.downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:fdi.downloadSource]];
            
            else
            
                fdi.downloadTask = [self.session downloadTaskWithResumeData:fdi.taskResumeData];
            

            // Keep the new taskIdentifier.
            fdi.taskIdentifier = fdi.downloadTask.taskIdentifier;

            // Start the download.
            [fdi.downloadTask resume];

            // Indicate for each file that is being downloaded.
            fdi.isDownloading = YES;
        
    

我的下载和更新进度条的方法 -

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
 
   double Progress = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
   NSLog(@"Progressview progress : %f",Progress);

if (totalBytesExpectedToWrite == NSURLSessionTransferSizeUnknown)

    NSLog(@"Unknown transfer size");

else

    [self performSelectorOnMainThread:@selector(updateProgress:) withObject:[NSString stringWithFormat:@"%f",Progress] waitUntilDone:NO];
 


- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
 
 NSError *error;
 NSFileManager *fileManager = [NSFileManager defaultManager];
 NSString *destinationFilename = downloadTask.originalRequest.URL.lastPathComponent;
 NSURL *destinationURL = [self.docDirectoryURL URLByAppendingPathComponent:destinationFilename];

 if ([fileManager fileExistsAtPath:[destinationURL path]])
 
    [fileManager removeItemAtURL:destinationURL error:nil];
 
 BOOL success = [fileManager copyItemAtURL:location
                                    toURL:destinationURL
                                    error:&error];
 if (success)
  
    [[NSOperationQueue mainQueue] addOperationWithBlock:^
        NSLog(@"Download completed!");
        NSLog(@"destination file name : %@!",destinationFilename);
        NSLog(@"Part id of file name : %@!",self.part_id);
        [self performSelectorOnMainThread:@selector(updateProgress:) withObject:[NSString stringWithFormat:@"1.0"] waitUntilDone:NO];

        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

        NSString *filenameValue=[NSString stringWithFormat:@"%@",destinationFilename];
        NSString *hideExtension=[filenameValue substringToIndex:filenameValue.length-4];
        NSLog(@"filenameValue == %@", filenameValue);

        [self DBUpdateVideoURLStatus:self.part_id andFileName:filenameValue];
        [self DBInsertDownloads:self.part_id andFileName:filenameValue];

        UIAlertView *alert=[[UIAlertView alloc]initWithTitle:NSLocalizedString(@"Success", @"Success message") message:[NSString localizedStringWithFormat:@"%@ downloaded successfully!",hideExtension] delegate:self cancelButtonTitle:NSLocalizedString(@"Ok", @"Ok action") otherButtonTitles:nil];
        alert.tag = 1;
        [alert show];
        [alert release];
        [self.session finishTasksAndInvalidate];
    ];
 
 else
  
    NSLog(@"Unable to copy temp file. Error: %@", [error localizedDescription]);
  


-(void)updateProgress:(id)progress

  float currentProgress = [progress floatValue];
  [self.downloadProgress setProgress:currentProgress animated:YES];
  [self.downloadProgress setNeedsDisplay];
  [self.tblview reloadData];

【问题讨论】:

您使用的是单个会话对象还是多个会话对象?你为什么打电话给finishTasksAndInvalidate?如果进度视图没有更新,您是否看到“Progressview 进度...”消息,或“未知传输大小”或什么也没有?当您说“与上次删除的文件一起下载”时,您是什么意思? @Rob 我一次下载一个文件。哦,所以不需要 finishTasksAndInvalidate.. 如果进度视图没有更新,但文件正在下载,则不需要。我没有收到任何消息未知传输大小。 您需要进行更多诊断以准确识别故障所在。 didWriteData 没有被调用吗? updateProgress 没有被调用吗? downloadProgress 是非nil 值吗?从你的问题不清楚。请编辑问题,详细说明您迄今为止所做的诊断。 @Rob 我很欣赏诊断,我知道这些事情当我尝试下载并删除它并再次下载尝试在已失效的会话中创建任务 *** 终止应用程序由于未捕获的异常“NSGenericException”,原因:“在已失效的会话中创建的任务” 【参考方案1】:

你说:

当我尝试下载并删除它并再次下载时尝试在已失效的会话中创建任务 *** 由于未捕获的异常“NSGenericException”而终止应用程序,原因:“在具有已作废'

这是因为您正在调用finishTasksAndInvalidate,它告诉NSURLSession 它不仅应该完成所有队列任务,还应该使会话无效并且不允许更多任务。但是还有另一个任务要运行,但是您使会话无效。

底线,随意取消任务,但如果您要为同一个会话对象启动更多任务,请不要使会话对象无效。

【讨论】:

【参考方案2】:

我注意到一个错误:

mainQueue 在主线程上处理,因此您不应从在主队列上执行的块中调用 performSelectorOnMainThread。

在下载任务结束时到达主线程的标准模式是将异步调度到主队列,而不是像您所做的那样向主队列添加操作。

【讨论】:

正确,但与手头的问题无关。 @malhal。你能更新我的代码并发布正确的代码吗?了解一下就好了 要修复的东西太多,我不完全理解您试图实现的下载行为。如果我是你,我会搜索如何使用 NSURLSession 下载多个文件以获取正确模式的示例。 @malhal 你能给我推荐一些最好的多重下载示例吗?我已经足够好了。【参考方案3】:

您能否尝试更改以下代码并告诉我们结果如何:

-(void)updateProgress:(id)progress

    dispatch_async(dispatch_get_main_queue(), ^

        float currentProgress = [progress floatValue];
        [self.downloadProgress setProgress:currentProgress animated:YES];
        [self.downloadProgress setNeedsDisplay];

    );
    [self.tblview reloadData];

【讨论】:

兄弟当我删除它并再次下载时它会崩溃我收到消息崩溃 - 尝试在已失效的会话中创建任务。找不到问题出在哪里,上面有人建议诊断问题,我做到了,这也是崩溃的原因和更新进度

获取所有视图控制器中的 NSURLSession 下载进度

】获取所有视图控制器中的NSURLSession下载进度【英文标题】:getNSURLSessiondownloadprogressinallviewcontrollers【发布时间】:2017-05-3015:36:24【问题描述】:所以我有一个FirstViewController,我可以在其中下载带有进度视图的视频,并且使用... 查看详情

NSURLSession,数据任务转换为下载任务后,后台无法下载

】NSURLSession,数据任务转换为下载任务后,后台无法下载【英文标题】:NSURLSession,afterthedatataskisconvertedtodownloadtask,itcan\'tdownloadinbackground【发布时间】:2016-05-0716:36:18【问题描述】:如果我运行以下代码并让应用程序在后台运行... 查看详情

NSURLSession 后台任务:避免重复

】NSURLSession后台任务:避免重复【英文标题】:NSURLSessionbackgroundtask:avoidduplicates【发布时间】:2014-05-0610:35:09【问题描述】:我是NSURLSession和特别是后台下载任务的新手。有没有办法查询NSURLSession以返回后台任务列表?似乎可以... 查看详情

如何使用界面更新异步任务中的进度条

...一个应用程序,其中我使用了Fragment类和另一个Async类来下载两个不同的类现在我必须显示进度条水平更新进度条在onProgressUpdate中发生了多少下载。但是onProgressUpdate回调不起作用的接 查看详情

显示下载进度条

】显示下载进度条【英文标题】:showdownloadprogressbar【发布时间】:2021-10-2604:24:50【问题描述】:在我的应用程序中,我使用执行器服务从url下载文件。现在我想添加一个水平进度条来显示下载进度。但我面临错误。如何在不使... 查看详情

NSURLSession dataTaskWithRequest 进度跟踪

】NSURLSessiondataTaskWithRequest进度跟踪【英文标题】:NSURLSessiondataTaskWithRequestprogresstracking【发布时间】:2015-05-2722:27:51【问题描述】:我正在使用NSURLSessiondataTask和NSOoperationQueue来下载具有多个连接的文件以获得更快的速度。从NSURL... 查看详情

更改视图控制器后如何更新 UIProgressView 以显示 NSUrlSession 下载进度

】更改视图控制器后如何更新UIProgressView以显示NSUrlSession下载进度【英文标题】:HowtoUpdateUIProgressViewtoDisplayNSUrlSessionDownloadProgressAfterChangingViewController【发布时间】:2014-03-2403:55:46【问题描述】:我有一个ViewController,用户可以点... 查看详情

NSURLSession 下载任务 - Xamarin iOS F#

】NSURLSession下载任务-XamariniOSF#【英文标题】:NSURLSessionDownloadTask-XamariniOSF#【发布时间】:2018-01-2918:24:04【问题描述】:我正在尝试从F#中的C#Xamarin.IOS实现以下方法:NSUrlSession.SharedSession.CreateDownloadTask(Request,(data,response,error)=>if... 查看详情

NSURLSession,上传任务 - 获取传输的实际字节

】NSURLSession,上传任务-获取传输的实际字节【英文标题】:NSURLSession,uploadtask-Getactualbytestransferred【发布时间】:2015-05-2906:40:48【问题描述】:我收到错误报告,说我的iOS应用程序在慢速连接时无法上传图片。虽然我的超时时间... 查看详情

NSURLSession 下载任务使用默认会话配置在调试中增加内存

】NSURLSession下载任务使用默认会话配置在调试中增加内存【英文标题】:NSURLSessiondownloadtaskgrowsmemoryindebugwithdefaultsessionconfig【发布时间】:2014-12-0319:55:53【问题描述】:我有一个在iOS7及更高版本上使用NSURLSession下载文件的应用... 查看详情

AFNetworking/NSURLSession耗时长创建100多个任务下载文件

】AFNetworking/NSURLSession耗时长创建100多个任务下载文件【英文标题】:AFNetworking/NSURLSessiontakeslongtocreatemorethan100taskstodownloadfiles【发布时间】:2017-08-1115:15:40【问题描述】:我的应用程序需要下载许多文件,我使用for循环来创建下... 查看详情

表单最小化时在任务栏中显示进度条

...进度条逐渐变成绿色的?谁能告诉我该怎么做?更新:我下载了windowsapi代码包并在我的项目 查看详情

如果我想使用 NSURLSession 获取图像下载的进度,我是不是必须使用下载方法而不是数据?

】如果我想使用NSURLSession获取图像下载的进度,我是不是必须使用下载方法而不是数据?【英文标题】:IfIwanttogettheprogressofanimagedownloadusingNSURLSession,doIhavetousethedownloadmethodsoverdata?如果我想使用NSURLSession获取图像下载的进度,我... 查看详情

使用 NSURLSession 如何在取消下载任务时获取接收到的数据或临时文件位置

】使用NSURLSession如何在取消下载任务时获取接收到的数据或临时文件位置【英文标题】:withNSURLSessionhowtogetreceiveddataortempfilelocationoncancellingdownloadtask【发布时间】:2014-12-0405:25:49【问题描述】:我正在使用NSURLSession下载多个文件... 查看详情

NSURLSession,多数据任务,completionHandler

】NSURLSession,多数据任务,completionHandler【英文标题】:NSURLSession,multipledatatasks,completionHandler【发布时间】:2015-10-1100:24:13【问题描述】:我想使用NSURLSession和dataTaskWithURL:completionHandler:将4个不同的URL下载到NSData对象中。我知道... 查看详情

将进度从 NSURLSession 发送到 ViewController [swift - iOS]

】将进度从NSURLSession发送到ViewController[swift-iOS]【英文标题】:SendProgressfromNSURLSessiontoViewController[swift-iOS]【发布时间】:2016-02-0710:01:17【问题描述】:我正在开发一个在后台处理一些下载的应用程序。我将文件移动到文档目录并... 查看详情

Java 中的 Windows 7 任务栏进度条

】Java中的Windows7任务栏进度条【英文标题】:Windows7TaskbarProgressBarinJava【发布时间】:2011-01-1103:24:57【问题描述】:我想知道当文件操作正在进行时,是否可以像Windows资源管理器那样在任务栏上显示进度条?我看到很多例子,但... 查看详情

C#任务栏中的Windows 7进度条?

】C#任务栏中的Windows7进度条?【英文标题】:Windows7progressbarintaskbarinC#?【发布时间】:2010-11-2017:17:27【问题描述】:如果您在Windows7测试版中注意到,如果您复制文件或其他系统操作,任务栏中的Windows资源管理器图标将填满一... 查看详情