3

I am working with a Non-ARC project, where i have to downloads video's, and once downloaded i will be displaying them. I am using NSURLSession for downloading it.

Problem is in Progress bar. I can download first two or three file correctly through progress bar when i start downloading fourth file, the progress bar is not updating properly but file s getting downloaded with last deleted file.

Getting crash on this when deleting and downloading again n again

Attempted to create a task in a session that has been invalidated

 - (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;
        }
    }

My Methods for downloading and updating progress bar -

- (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];
}
Tirth
  • 7,801
  • 9
  • 55
  • 88
ChenSmile
  • 3,401
  • 4
  • 39
  • 69
  • Are you using a single session object or multiple ones? Why are you calling `finishTasksAndInvalidate`? If the progress view is not updating, are you seeing the "Progressview progress ..." messages, or "Unknown transfer size" or nothing? And what do you mean when you say "getting downloaded with last deleted file"? – Rob May 04 '16 at 06:41
  • @Rob I am downloading single file at a time. oh so no need of finishTasksAndInvalidate.. No if progress view is not updating, but the file s downloading. i do not get any message Unknown transfer size. – ChenSmile May 04 '16 at 06:51
  • You need to do some more diagnostics to identify precisely where the breakdown is. Is `didWriteData` not getting called? Is `updateProgress` not getting called? Is `downloadProgress` a non-`nil` value? It's unclear from your question. Please edit the question with details on what diagnostics you've done thus far. – Rob May 04 '16 at 06:56
  • @Rob i appreciate for diagonostics and i got to know these things When i am trying to download and delete it and again download Attempted to create a task in a session that has been invalidated *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Task created in a session that has been invalidated' – ChenSmile May 04 '16 at 07:06

3 Answers3

3

You said:

When i am trying to download and delete it and again download Attempted to create a task in a session that has been invalidated *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Task created in a session that has been invalidated'

This is because you're calling finishTasksAndInvalidate, which tells NSURLSession that it should not only finish all queues tasks, but invalidate the session and not permit any more tasks. But there's another task to run, but you invalidated the session.

Bottom line, feel free to cancel a task, but don't invalidate the session object if you're going to start more tasks for the same session object.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

Well I noticed one mistake:

mainQueue is processed on the main thread so you should not call performSelectorOnMainThread from the block performed on the main queue.

The standard pattern to get to the main thread at the end of a download task is to dispatch async onto main queue, rather than add an operation to the mainQueue as you have done.

malhal
  • 26,330
  • 7
  • 115
  • 133
  • True, but unrelated to the problem at hand. – Rob May 04 '16 at 06:53
  • @malhal. could u update in my code and post with correct one. it would be good to understand – ChenSmile May 04 '16 at 06:55
  • There are too many things to fix and I don't fully understand the download behavior you are trying to achieve. If I was you I would search for an example of how to download multiple files using NSURLSession to get the pattern right. – malhal May 04 '16 at 06:58
  • @malhal could u suggest me some best multiple download sample. i m got getting good enough. – ChenSmile May 04 '16 at 08:12
-1

Can you please try changing the following code and let us know what it results:

-(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];
}
Manab Kumar Mal
  • 20,788
  • 5
  • 31
  • 43
  • bro it get crash when i delete it and again download i m getting message crash - Attempted to create a task in a session that has been invalidated. Not able to find where is the issue, above people suggested to diagnostic the problem, i did and here s the cause of crash and update progress also – ChenSmile May 04 '16 at 08:06