Невозможно переместить файл после загрузки фона: "Нет такого файла"

У меня есть приложение, использующее backgroundSessionConfiguration экземпляр NSURLSession для обработки некоторых NSURLSessionDownloadTask задач. Задачи создаются правильно и завершают загрузку, но в URLSession:downloadTask:didFinishDownloadingToURL:, когда я перехожу, чтобы переместить загруженный файл из location в постоянное место на диске, я иногда (часто читаю) получаю ошибку:

NSUnderlyingError=0x178247890 "The operation couldn’t be completed. No such file or directory"

Как будто скачанный файл очищается из временного каталога (../Library/Caches/com.apple.nsnetworkd/..), прежде чем у меня появится возможность его переместить.

Запуск операции для того же удаленного файла будет вести себя в обоих направлениях, при этом все остальные факторы будут равны, поэтому я не смог идентифицировать что-либо, что могло бы заставить его иногда работать.

В любом случае, чтобы этот файл задерживался достаточно долго, чтобы переместить его на место после его завершения?

Изменить: я также вижу это с некоторой частотой для обычных (а не фоновых) сеансов, а также

Ответ 1

Временные файлы удаляются автоматически после выхода из этого метода, вы можете попытаться сохранить этот возвращенный файл как 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

Попробуйте это

- (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

Включение в это с помощью Swift под iOS 8, копирование или перемещение файла не сработало. Чтение файла temp напрямую и запись обратно работали. Код создает изображение из загруженного изображения:

var fileHandle:NSFileHandle = NSFileHandle(forReadingAtPath: location.path!)!
var data:NSData = fileHandle.readDataToEndOfFile()
var image:UIImage = UIImage(data: data)!
imageView.image = image

Ответ 4

Это лучший способ сделать это

- (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];
}