My app supports opening a document in place. However, under a certain condition, I would like to copy it to my local sandbox. I followed Copy file from iOS 11 Files app to sandbox and used [NSURL startAccessingSecurityScopedResource].
I verified that the file exists, but the copy operation fails, reporting that the file doesn't exist.
Following is my code in the app delegate.
if (openedInPlace) {
NSString *urlString = [url absoluteString];
if ([urlString containsString:@"/Downloads/"]) {
NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSError *coordinatorError = nil;
__block BOOL leaveInPlace = YES;
__block NSURL *fileURL;
[fileCoordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingWithoutChanges error:&coordinatorError byAccessor:^(NSURL *newURL)
{
// Copy to local inbox
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *docs = [fm URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
NSURL *inbox = [docs URLByAppendingPathComponent:@"Inbox" isDirectory:YES];
//NSURL *fileURL = [inbox URLByAppendingPathComponent:[url lastPathComponent]];
fileURL = [inbox URLByAppendingPathComponent:@"test_doc.ptw"];
BOOL result;
NSLog(@"Copy from %@ to %@", newURL, fileURL);
result = [newURL startAccessingSecurityScopedResource];
NSLog(@"startAccessingSecurityScopedResource %@", result ? @"succeeded" : @"did not succeed.");
result = [fm fileExistsAtPath:newURL.path];
NSLog(@"File %@ %@", newURL.path, result ? @"exists" : @"doesn't exist");
NSError *copyError = nil;
[fm copyItemAtURL:newURL toURL:fileURL error:©Error];
if (!copyError)
{
// OK
leaveInPlace = NO;
}
else
{
NSLog(@"Files app error: %@", copyError);
leaveInPlace = YES;
result = [fm fileExistsAtPath:newURL.path];
NSLog(@"File %@ %@", newURL.path, result ? @"exists" : @"doesn't exist");
}
[newURL stopAccessingSecurityScopedResource];
}];
openedInPlace = leaveInPlace;
if (! openedInPlace)
url = fileURL;
}
}
And here is the log:
Copy from file:///private/var/mobile/Containers/Shared/AppGroup/E6E86AC8-4E2F-45B2-9842-FB6AAE29D31E/File%20Provider%20Storage/Downloads/Bloc%202.ptw to file:///var/mobile/Containers/Data/Application/912852F7-9C16-4D9C-B9C9-6A0126C92C40/Documents/Inbox/test_doc.ptw
startAccessingSecurityScopedResource succeeded
File /private/var/mobile/Containers/Shared/AppGroup/E6E86AC8-4E2F-45B2-9842-FB6AAE29D31E/File Provider Storage/Downloads/Bloc 2.ptw exists
Files app error: Error Domain=NSCocoaErrorDomain Code=4 "The file “Bloc 2.ptw” doesn’t exist." UserInfo={NSSourceFilePathErrorKey=/private/var/mobile/Containers/Shared/AppGroup/E6E86AC8-4E2F-45B2-9842-FB6AAE29D31E/File Provider Storage/Downloads/Bloc 2.ptw, NSUserStringVariant=(
Copy
), NSDestinationFilePath=/var/mobile/Containers/Data/Application/912852F7-9C16-4D9C-B9C9-6A0126C92C40/Documents/Inbox/test_doc.ptw, NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/E6E86AC8-4E2F-45B2-9842-FB6AAE29D31E/File Provider Storage/Downloads/Bloc 2.ptw, NSUnderlyingError=0x28252c570 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
File /private/var/mobile/Containers/Shared/AppGroup/E6E86AC8-4E2F-45B2-9842-FB6AAE29D31E/File Provider Storage/Downloads/Bloc 2.ptw exists
I tried using "url" instead of "newURL" in the fileCoordinator block.
The error message was misleading, the problem was with the copy destination, not the source as the message indicated. The destination Inbox folder did not exist in my app. I now copy the file "test_doc.ptw" to the Documents directory and all is fine.