Summary:
When background NSURLSession has downloaded file and the application isn't running, when you start application, URLSession:downloadTask:didFinishDownloadingToURL: method is called with 'location' pointing to a missing file.
It prints:
Error. File not found
Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn't be completed. (Cocoa, error 4)"{NSSourceFilePathErrorKey=/private/var/mobile/Containers/Data/Application/7C039B25-95DC-4CC9-B73D-477E55A53A66/Library/Caches/com.apple.nsurlsessiond/Downloads/bundle.id/CFNetworkDownload_CZizB9.tmp, NSUserStringVariant=(
Move
), NSDestinationFilePath=/var/mobile/Containers/Data/Application/13E0352D-4C4F-4257-8595-F27CD874756D/Library/Caches/File.zip.tmp, NSFilePath=/private/var/mobile/Containers/Data/Application/7C039B25-95DC-4CC9-B73D-477E55A53A66/Library/Caches/com.apple.nsurlsessiond/Downloads/bundle.id/CFNetworkDownload_CZizB9.tmp, NSUnderlyingError=0x17424b5e0 "The operation couldn't be completed. No such file or directory"}
Steps to Reproduce:
Run the application. It starts downloading file.
Close the application completely (force it to close by swiping out its preview). File is still being downloaded in the background.
Wait enough time for the file to be downloaded completely.
Run the application.
URLSession:downloadTask:didFinishDownloadingToURL: method is called. "location" parameter points to file that doesn't exists.
Actual Results:
URLSession:downloadTask:didFinishDownloadingToURL: is called with a 'locaton' that points to a nonexisting file.
'location' looks like a correct url, example:
file:///private/var/mobile/Containers/Data/Application/7C039B25-95DC-4CC9-B73D-477E55A53A66/Library/Caches/com.apple.nsurlsessiond/Downloads/bundle.id/CFNetworkDownload_CZizB9.tmp
NSFileManager:fileExistsAtPath: shows that the file doesn't exist.
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:dest_path] error:&error] returns false and the error saying that "The operation couldn't be completed. No such file or directory"
Description
Summary: When background NSURLSession has downloaded file and the application isn't running, when you start application, URLSession:downloadTask:didFinishDownloadingToURL: method is called with 'location' pointing to a missing file.
Here is the code (https://gist.github.com/andreysm/732aee1bc54a4664b967):
NSURLSessionConfiguration * config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"DownloadAsyncSession"]; config.sessionSendsLaunchEvents = NO; download_async_session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:nil];
...
(void)URLSession:(NSURLSession )session downloadTask:(NSURLSessionDownloadTask )downloadTask didFinishDownloadingToURL:(NSURL *)location { if (![[NSFileManager defaultManager] fileExistsAtPath: [location path]]) { NSLog(@"Error. File not found"); }
NSError * error = nil; BOOL ok = [[NSFileManager defaultManager] moveItemAtPath:[location path] toPath:dest_path error:&error]; if (ok) { res.info = [dest_path UTF8String]; } else { NSLog(@"Error: %@", error); } }
It prints: Error. File not found Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn't be completed. (Cocoa, error 4)"{NSSourceFilePathErrorKey=/private/var/mobile/Containers/Data/Application/7C039B25-95DC-4CC9-B73D-477E55A53A66/Library/Caches/com.apple.nsurlsessiond/Downloads/bundle.id/CFNetworkDownload_CZizB9.tmp, NSUserStringVariant=( Move ), NSDestinationFilePath=/var/mobile/Containers/Data/Application/13E0352D-4C4F-4257-8595-F27CD874756D/Library/Caches/File.zip.tmp, NSFilePath=/private/var/mobile/Containers/Data/Application/7C039B25-95DC-4CC9-B73D-477E55A53A66/Library/Caches/com.apple.nsurlsessiond/Downloads/bundle.id/CFNetworkDownload_CZizB9.tmp, NSUnderlyingError=0x17424b5e0 "The operation couldn't be completed. No such file or directory"}
Steps to Reproduce:
Expected Results: Expected that method URLSession:downloadTask:didFinishDownloadingToURL: is called with a 'locaton' that points to an existing temporary file that I could move to a permanent location before it is deleted. It is documented at https://developer.apple.com/library/watchos/documentation/Foundation/Reference/NSURLSessionDownloadDelegate_protocol/index.html#//apple_ref/occ/intfm/NSURLSessionDownloadDelegate/URLSession:downloadTask:didFinishDownloadingToURL:
Actual Results: URLSession:downloadTask:didFinishDownloadingToURL: is called with a 'locaton' that points to a nonexisting file.
'location' looks like a correct url, example: file:///private/var/mobile/Containers/Data/Application/7C039B25-95DC-4CC9-B73D-477E55A53A66/Library/Caches/com.apple.nsurlsessiond/Downloads/bundle.id/CFNetworkDownload_CZizB9.tmp
NSFileManager:fileExistsAtPath: shows that the file doesn't exist.
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:dest_path] error:&error] returns false and the error saying that "The operation couldn't be completed. No such file or directory"
Version: iOS 9
Notes: The same problem was raised by Guilherme Gusman (not me) at stackoverflow.com: http://stackoverflow.com/questions/28860112/nsurlsession-didfinishdownloadingtourl-temporary-downloaded-file-not-found
Configuration: iPhone 6
Product Version: Created: 2015-10-21T15:43:28.099400 Originated: 2015-10-21T00:00:00 Open Radar Link: http://www.openradar.me/23201555