I have an app using a backgroundSessionConfiguration
instance of NSURLSession
to handle some NSURLSessionDownloadTask
tasks. The tasks are created correctly, and finish downloading, but in URLSession:downloadTask:didFinishDownloadingToURL:
when I go to move the downloaded file from location
to a permanent spot on disk, I sometimes (read: often) get the error:
我有一个应用程序使用NSURLSession的backgroundSessionConfiguration实例来处理一些NSURLSessionDownloadTask任务。任务创建正确,并完成下载,但在URLSession:downloadTask:didFinishDownloadingToURL:当我将下载的文件从位置移动到磁盘上的永久位置时,我有时(读取:经常)得到错误:
NSUnderlyingError=0x178247890 "The operation couldn’t be completed. No such file or directory"
It's as though the downloaded file is being cleared out of the temp directory (../Library/Caches/com.apple.nsnetworkd/..) before I get a chance to move it.
就好像在我有机会移动它之前,下载的文件被清除了临时目录(../Library/Caches/com.apple.nsnetworkd/ ..)。
Running the operation for the same remote file will behave both ways with all other factors being equal, so I haven't been able to identify anything that would cause it to sometimes work.
对同一个远程文件运行操作将在所有其他因素相同的情况下表现两种方式,因此我无法识别任何会导致它有时工作的内容。
Is there anyway to ensure that this file will stick around long enough to move it into place once it's done?
无论如何要确保这个文件能够长时间保持足够的状态,一旦完成就将其移动到位?
Edit: I'm also seeing this with some frequency for normal (not background) sessions as well
编辑:我也看到了正常(非背景)会话的频率
4 个解决方案
#1
7
The temporary files are deleted automatically after exiting this method, you can try to hold this returned file as an NSData
and saves it directly into the desired location.
退出此方法后会自动删除临时文件,您可以尝试将此返回的文件保存为NSData并将其直接保存到所需位置。
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
// Create a NSFileManager instance
NSFileManager *fileManager = [[NSFileManager alloc] init];
// Get the documents directory URL
NSArray *documentURLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [documentURLs firstObject];
// Get the file name and create a destination URL
NSString *sendingFileName = [downloadTask.originalRequest.URL lastPathComponent];
NSURL *destinationUrl = [documentsDirectory URLByAppendingPathComponent:sendingFileName];
// Hold this file as an NSData and write it to the new location
NSData *fileData = [NSData dataWithContentsOfURL:location];
[fileData writeToURL:destinationUrl atomically:NO];
}
#2
3
Try this
尝试这个
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *URLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [URLs objectAtIndex:0];
NSURL *originalURL = [[downloadTask originalRequest] URL];
if(originalURL)
destinationUrl = [documentsDirectory URLByAppendingPathComponent:[originalURL lastPathComponent]];
NSError *errorCopy;
[fileManager removeItemAtURL:destinationUrl error:NULL];
BOOL success = [fileManager copyItemAtURL:downloadURL toURL:destinationUrl error:&errorCopy];
if (success) {
} else {
}
}
#3
0
Ran into this using Swift under iOS 8, copy or move file did not work. Reading temp file directly and writing back out worked. Code creates image view from downloaded image:
在iOS 8下使用Swift进入这个,复制或移动文件不起作用。直接读取临时文件并写回来工作。代码从下载的图像创建图像视图:
var fileHandle:NSFileHandle = NSFileHandle(forReadingAtPath: location.path!)!
var data:NSData = fileHandle.readDataToEndOfFile()
var image:UIImage = UIImage(data: data)!
imageView.image = image
#4
0
This is the best way to do it
这是最好的方法
- (void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location{
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSArray *documentURLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [documentURLs firstObject];
// Get the file name and create a destination URL
NSString *sendingFileName = [downloadTask.response suggestedFilename];
NSURL *destinationUrl = [documentsDirectory URLByAppendingPathComponent:sendingFileName];
// Hold this file as an NSData and write it to the new location
NSData *fileData = [NSData dataWithContentsOfURL:location];
[fileData writeToURL:destinationUrl atomically:NO];
}
#1
7
The temporary files are deleted automatically after exiting this method, you can try to hold this returned file as an NSData
and saves it directly into the desired location.
退出此方法后会自动删除临时文件,您可以尝试将此返回的文件保存为NSData并将其直接保存到所需位置。
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
// Create a NSFileManager instance
NSFileManager *fileManager = [[NSFileManager alloc] init];
// Get the documents directory URL
NSArray *documentURLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [documentURLs firstObject];
// Get the file name and create a destination URL
NSString *sendingFileName = [downloadTask.originalRequest.URL lastPathComponent];
NSURL *destinationUrl = [documentsDirectory URLByAppendingPathComponent:sendingFileName];
// Hold this file as an NSData and write it to the new location
NSData *fileData = [NSData dataWithContentsOfURL:location];
[fileData writeToURL:destinationUrl atomically:NO];
}
#2
3
Try this
尝试这个
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *URLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [URLs objectAtIndex:0];
NSURL *originalURL = [[downloadTask originalRequest] URL];
if(originalURL)
destinationUrl = [documentsDirectory URLByAppendingPathComponent:[originalURL lastPathComponent]];
NSError *errorCopy;
[fileManager removeItemAtURL:destinationUrl error:NULL];
BOOL success = [fileManager copyItemAtURL:downloadURL toURL:destinationUrl error:&errorCopy];
if (success) {
} else {
}
}
#3
0
Ran into this using Swift under iOS 8, copy or move file did not work. Reading temp file directly and writing back out worked. Code creates image view from downloaded image:
在iOS 8下使用Swift进入这个,复制或移动文件不起作用。直接读取临时文件并写回来工作。代码从下载的图像创建图像视图:
var fileHandle:NSFileHandle = NSFileHandle(forReadingAtPath: location.path!)!
var data:NSData = fileHandle.readDataToEndOfFile()
var image:UIImage = UIImage(data: data)!
imageView.image = image
#4
0
This is the best way to do it
这是最好的方法
- (void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location{
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSArray *documentURLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [documentURLs firstObject];
// Get the file name and create a destination URL
NSString *sendingFileName = [downloadTask.response suggestedFilename];
NSURL *destinationUrl = [documentsDirectory URLByAppendingPathComponent:sendingFileName];
// Hold this file as an NSData and write it to the new location
NSData *fileData = [NSData dataWithContentsOfURL:location];
[fileData writeToURL:destinationUrl atomically:NO];
}