iOS Background Transfer - com.apple.nsurlsessiond folder full of tmp files
Asked Answered
M

2

13

We've written a media application that allows you to get a list of latest videos as json list using BACKGROUND FETCH

then it uses BACKGROUND TRANSFER to tell iOS to download the video one by one and go back to sleep and to wake the app when its done.

It does all that but we've noticed that Space Usage is growing and growing.

We added code to clear all downloaded videos but space usage stayed hi in settings.

We downloaded the app folders using Xcode > Organizer> Devices and found the BACKGROUND TRANSFER tmp folder was dull of tmp files.

Shouldn't these be getting cleared out

This is in general the code I use. I think the main is I attach multiple DownloadTask(can be up to 30) to one background session. files vary in size from movies to pdfs.

NSURLSession * backgroundSession_ = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];


backgroundSession_ = [NSURLSession sessionWithConfiguration:urlSessionConfigurationBACKGROUND_
                                                   delegate:self
                                              delegateQueue:[NSOperationQueue mainQueue]];

NSOperationQueue *mainQueue_ = [NSOperationQueue mainQueue];



NSURLSessionDownloadTask * downloadTask_ = [backgroundSession_ downloadTaskWithURL:url_];

downloadStarted_ = TRUE;
[downloadTask_ resume];

enter image description here

Mango answered 3/7, 2015 at 15:47 Comment(0)
B
1

Try something like this before returning from didFinishDownloadingToURL:

// App's Documents directory path
NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];

// Creating the path for the downloaded file
docsPath = [docsPath stringByAppendingPathComponent:downloadTask.response.suggestedFilename];

// Moving the file from temp location to App's Documents directory
[[NSFileManager defaultManager] moveItemAtPath:location.path toPath:docsPath error:NULL];

The documentation states that you should "move the file to a permanent location in your app’s sandbox container directory before returning from this delegate method" (perhaps the Documents directory).

The temp files that gets cleared out after you return from didFinishDownloadingToURL (or if the download failed) - at the OS's discretion (usually under memory pressure).

Batangas answered 13/7, 2015 at 9:0 Comment(0)
M
0

I have the same issue but in a bit different circumstances: on older devices (iPhone 4S or older) the app is usually killed during the background fetching by the OS. Probably to free memory. In this case the tmp files are retained (and untracked). Next time the app has an opportunity to fetch, new files are created... and this cycle goes on and on till the user recognises the app uses 4gb of storage space - and deletes it.

I haven't found the perfect solution yet - even after I set the background configuration's -NSURLSessionConfiguration URLCache to a custom one (documentation says it's nil by default) with a path the same directory (defaultCacheDir/com.apple.nsurlsessiond/...) was used - but made a cleanup method and use it when I sure there is no download in progress.

+ (BOOL)clearCache:(NSError * __autoreleasing *)error
{
    __block BOOL successOnLegacyPath = NO;
    __block NSError *errorOnLegacyPath = nil;

    NSString *cacheDirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

    NSArray *allSubPaths = [[NSFileManager defaultManager] subpathsAtPath:cacheDirPath];

    if (!allSubPaths) {
        NSLog(@"No subpaths of cache:\n%@", cacheDirPath);
    } else {
        [allSubPaths enumerateObjectsUsingBlock:^(NSString *subpath, NSUInteger idx, BOOL *stop) {
static NSString * const kNSURLSessionPathComponent = @"nsurlsession";  // this is a non-documented way, Uncle Apple can change the path at any time
            if ([subpath containsString:kNSURLSessionPathComponent]) {
                successOnLegacyPath = [[NSFileManager defaultManager] removeItemAtPath:[cacheDirPath stringByAppendingPathComponent:subpath]
                                                                                 error:&errorOnLegacyPath];
                if (!successOnLegacyPath) {
                    NSLog(@"Error while deleting cache subpath:\n%@\nError:\n%@", subpath, errorOnLegacyPath);
                }
                // First we find is the root > bail out
                *stop = YES;
            }
        }];
    }

    if (!successOnLegacyPath && !errorOnLegacyPath) {
        // Couldn't find the nsurlsession's cache directory
        if (error) *error = [NSError errorWithDomain:NSCocoaErrorDomain
                                                code:NSFileNoSuchFileError
                                            userInfo:nil];

        // OR
        successOnLegacyPath = YES;
    }

    return successOnLegacyPath;
}

This is not a solution and this is recommended to use if no download is in progress. Haven't tested what's happening if there are running downloads and trying to delete the tmp files.

Even if I find a solution, the previously created tmp files still remain untracked so those need to be deleted by a method like this.

Btw, this seems to be the same question - without conclusion.

Mallemuck answered 30/7, 2015 at 14:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.