Here’s part of a NSURLSession download task handler:
> NSURLSessionDownloadTask * const task = [session
> downloadTaskWithURL:[NSURL URLWithString:[NSString
> stringWithUTF8String:argv[1]]] completionHandler:^(NSURL *location,
> NSURLResponse *response, NSError *error) {
> if (!error) {
> NSCParameterAssert(location);
> NSCParameterAssert(response);
>
> NSURL * const plannedDestination = [NSURL
> fileURLWithPath:response.suggestedFilename isDirectory:NO];
> NSURL * stagedLocation = nil;
> NSURL * actualDestination = nil;
>
> NSCAssert(plannedDestination, @"Creating destination URL
> failed");
> if (CgMoveFileToDestinationTemporaryDirectory(location,
> plannedDestination, &stagedLocation, &error) && [[NSFileManager
> defaultManager] replaceItemAtURL:plannedDestination
> withItemAtURL:stagedLocation
> backupItemName:CgBackupFilename(plannedDestination.path.lastPathComponent)
> options:(NSFileManagerItemReplacementUsingNewMetadataOnly |
> NSFileManagerItemReplacementWithoutDeletingBackupItem)
> resultingItemURL:&actualDestination error:&error]) {
> gbprintln(@"%@", actualDestination.path);
(The rest is just error handling.)
I thought the downloaded temporary file lasts until the handler ends. The “if”
statement used to be just a call to NSFileManager “- moveItemAtURL: toURL:
error:”, but that just gets an error whenever the destination file already
exists. The replaceItemAtURL… used in the current code lets me shift the
original file (renamed based on the results of the “CgBackupFilename” function)
aside to put the downloaded file in its place. But this API does not work
across volumes. I added the “CgMoveFileToDestinationTemporaryDirectory”
function to find/create the temporary work directory for the destination file’s
volume and move the source file there. If the source and destination files use
the same volume, the source is unmoved.
Everything has been working for the past few trials, then spontaneously stopped
working. Now I’m getting '“TempFile.whatever” doesn’t exist’ errors. I made a
hypothesis and possibly confirmed it by fixing the code by taking out the
same-volume check; the source file is always moved to the destination file’s
volume’s temporary work directory, even when the source file uses the same
volume.
I guess that the same-volume check and/or returning the original source file
when the check passes expires either a timer or stack frame limit by
NSURLSession and kills the temporary file before I can do my real work. I guess
NSURLSession stores its temporary files outside the user’s temporary work
directory, so removing the same-volume check always creates a move and
therefore avoids the automatic deletion.
Am I right (or nearly so)? Is what I did the way to fix it?
—
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/macnetworkprog/archive%40mail-archive.com
This email sent to [email protected]