NSURLSessionDownloadTask not deleting the file when the app is closed by the user and the task was still active
Asked Answered
V

3

7

I have a NSURLSession and a NSURLSessionDownloadTask configured for downloading a file in background, if the download task in canceled by the user all the data is deleted and the storage space the file was using is freed, but if the app is closed from the multitasking dock the download task is terminated and gives an error but is not deleting the data and the temporal data for the file is still occupying storage space and is never freed. What do i need to do in order to free the space ?

This is my NSURLSession configuration and error handling:

- (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; }
Vitelline answered 28/7, 2015 at 16:49 Comment(5)
How are you deleting the data when the user cancels the download?Troublemaker
Hi MikeAtNobel it is deleted automatically I don't have to do anything. Whe the user touch the button cancel I call [NSURLSessionDownloadTask cancel]Vitelline
Is that called when the app is force quit?Troublemaker
No is not canceled, this is the task download id before closing the app: <__NSCFBackgroundDownloadTask: 0x146d2f990>{ taskIdentifier: 2 } then I close the app while the task is still downloading and when I open the app again I get the next error: Task: <__NSCFBackgroundDownloadTask: 0x135e24460>{ taskIdentifier: 3 } completed with error: unsupported URL, 18446744073709550614Vitelline
There is no way to call '[NSURLSessionDownloadTask cancel]' because the app was in background and is close from the multitasking dock.Vitelline
V
6

ok after more than 10 days of try and fail I found the solution, first of all there are two case scenarios when the user close the app and there is an active download in background, please take in to account that for this cases the download task is never intended to be resumed.

scenario 1. when the user close the app but is still active, the - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error is called and the temporal file that was using for the download goes directly to the temp directory of the app, in this case the - (void)applicationWillTerminate:(UIApplication *)application is called but the delegate of the download task is called first. The solution is this case is to implement code to clean the temp directory every time the app is opened or let iOS to clean the temp folder, it is explained here when iOS is going to clean the temp file:

When does iOS clean the local app ./tmp directories?

scenario 2. when the user close the app in background mode the app is terminated and the next time the app is opened the - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error is called and the temporal file that was using for the download is stored in the NSCachesDirectory in the next directory:

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

The temporal file will be move to the temporal directory of the app the next time there is a new download.

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

Here is the code in order to delete the temporal 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 because it only work for this scenario its better to implement code to clean the temporal directory of the app every time is launched or let iOS to clean the temp folder so it will work for both scenarios.

Here is the code on how to clean the temporal directory of the app:

NSString *path = NSTemporaryDirectory();
NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
for (NSString *string in array) {
    [[NSFileManager defaultManager] removeItemAtPath:[path stringByAppendingPathComponent:string] error:nil];
}
Vitelline answered 4/8, 2015 at 11:34 Comment(2)
Finally I got solution. Thank you @Vitelline . I had some issue in my iOS app. :)Arrowood
@ajeet sharma welcome, please dont forget to vote for the postVitelline
B
0

First point is if you are configure nsurlsession with background configuration type. Then this type of session till runing if user kill the app. Second point if you want to clear space then you need to stop that session and manually write code for deleting temporary file from tmp folder.

Change session configuration type.

Backgammon answered 28/7, 2015 at 17:15 Comment(1)
This is borderline an acceptable answer. Is there any chance you can add more detail to some of the points you make in your answer? How can the session be stopped? Have you got an example of the manual code to delete temporary files? What should the session configuration type be changed to, and why?Joiner
T
0

There's a method in the AppDelegate called - (void)applicationWillTerminate:(UIApplication *)application. You can try either calling [NSURLSessionDownloadTask cancel]; from there; or try setting a flag to indicate to the app there was a download in progress when the app was closed and delete the data the next time the app is opened.

Troublemaker answered 30/7, 2015 at 22:17 Comment(2)
- (void)applicationWillTerminate:(UIApplication *)application is not getting call when you close the app from the multitasking dock.Vitelline
Sorry, I should've caught that one. Since the app is in the background when it's closed, that method doesn't get called. Looking at Apple's documentation ( developer.apple.com/library/ios/documentation/iPhone/Conceptual/… ) seems to indicated there may be no standard way of dealing with data in this state. You may need to figure out a custom way of deciding if the data in the download location is good.Troublemaker

© 2022 - 2024 — McMap. All rights reserved.