Skip to content

Instantly share code, notes, and snippets.

@mikeabdullah
Last active January 6, 2024 07:31
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mikeabdullah/4740463 to your computer and use it in GitHub Desktop.
Save mikeabdullah/4740463 to your computer and use it in GitHub Desktop.
Atomic file copying
- (BOOL)atomicCopyItemAtURL:(NSURL *)sourceURL
toURL:(NSURL *)destinationURL
error:(NSError **)outError
{
NSFileManager *manager = [NSFileManager defaultManager];
// First copy into a temporary location where failure doesn't matter
NSURL *tempDir = [manager URLForDirectory:NSItemReplacementDirectory
inDomain:NSUserDomainMask
appropriateForURL:destinationURL
create:YES
error:outError];
if (!tempDir) return NO;
NSURL *tempURL = [tempDir URLByAppendingPathComponent:[destinationURL lastPathComponent]];
BOOL result = [manager copyItemAtURL:sourceURL toURL:tempURL error:outError];
if (result)
{
// Move the complete item into place, replacing any existing item in the process
NSURL *resultingURL;
result = [manager replaceItemAtURL:destinationURL
withItemAtURL:tempURL
backupItemName:nil
options:NSFileManagerItemReplacementUsingNewMetadataOnly
resultingItemURL:&resultingURL
error:outError];
if (result)
{
NSAssert([resultingURL.absoluteString isEqualToString:destinationURL.absoluteString],
@"URL unexpectedly changed during replacement from:\n%@\nto:\n%@",
destinationURL,
resultingURL);
}
}
// Clean up
NSError *error;
if (![manager removeItemAtURL:tempDir error:&error])
{
NSLog(@"Failed to remove temp directory after atomic copy: %@", error);
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment