NSURLSessionDownloadTask does not delete the file when the application is closed by the user and the task is still active

I have NSURLSession and NSURLSessionDownloadTask configured to download a file in the background, if the download task deletes all data by the user and the file storage space is freed, but if the application is closed from the multitasking dock, the download task terminates and gives an error, but not deletes data, and temporary data for the file still takes up storage space and is never freed. What do I need to do to free up space?

This is my configuration and error handling NSURLSession :

 - (NSURLSession *)backgroundSession { static NSURLSession *session = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSURLSessionConfiguration *configuration; if ([[UIDevice currentDevice].systemVersion hasPrefix:@"7"]) configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.visyon.pr"]; else configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.visyon.pr"]; configuration.sessionSendsLaunchEvents =YES; session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; }); return session; } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if (error == nil) { NSLog(@"Task: %@ completed successfully", task ); } else { // [self hideActivity]; // [self showAlertBoxErrorDownload]; NSLog(@"Task: %@ completed with error: %@, %lu", task, [error localizedDescription], (long)error.code); } self.downloadTask = nil; } 
+4
source share
3 answers

ok after more than 10 days of attempts and failures, I found a solution, first of all, there are two scenarios of the case when the user closes the application and there is an active download in the background, please note that for these cases the download task is never intended to resume.

1. When the user closes the application, but is still active, it calls - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error , and the temporary file that was used to download directly gets to the temp directory of the application, in this case - (void)applicationWillTerminate:(UIApplication *)application , but the delegate of the download task is called the first. The solution is to implement code to clean the temp directory every time the application is open or let iOS clear the temporary folder, this is explained here when iOS is about to clear the temporary file:

When iOS cleans up directories on-premises / tmp?

2. When the user closes the application in the background, the application is terminated, and the next time the application is opened, it calls - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error , and the temporary file that used for download, stored in NSCachesDirectory in the following directory:

var/mobile/Containers/Data/Application/CA21-B6E8-3305A39/Library/Caches/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/CFNetworkDownload_M5o8Su.tmp

The temporary file will be moved to the temporary directory of the application at the next boot.

the solution here is to implement the code to delete all temporary files from Caches/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/ as soon as it starts - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error .

Here is the code to remove temporary files from NSCachesDirectory :

  NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[path stringByAppendingPathComponent:@"/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/"] error:nil]; for (NSString *string in array) { [[NSFileManager defaultManager] removeItemAtPath:[path stringByAppendingPathComponent:[NSString stringWithFormat:@"/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/%@", string]] error:nil]; } 

But since it only works for this scenario, it’s best to implement code to clear the application’s temporary directory each time it starts, or let iOS clear the temporary folder so that it works for both scenarios.

Here is the code on how to clear the temporary directory of the application:

 NSString *path = NSTemporaryDirectory(); NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil]; for (NSString *string in array) { [[NSFileManager defaultManager] removeItemAtPath:[path stringByAppendingPathComponent:string] error:nil]; } 
+4
source

The first point is if you configured nsurlsession with the background configuration type. Then this type of session is up to start if the user kills the application. The second point, if you want to clear the space, then you need to stop this session and manually write the code to delete the temporary file from the tmp folder.

Change the type of session configuration.

0
source

AppDelegate has a method called - (void)applicationWillTerminate:(UIApplication *)application . You can try either call [NSURLSessionDownloadTask cancel]; from there; or try setting a flag to indicate in the application when the download was started, when the application was closed and deleted data the next time the application is opened.

0
source

All Articles