I'm struggling to figure out how to rename an instance of a UIDocument
subclass in an iCloud folder. I've tried saving the document with the new URL…
func renameDocument(to name: String) {
let targetURL = document.fileURL.deletingLastPathComponent().appendingPathComponent(name)
.appendingPathExtension("<extension>")
document.save(to: targetURL, for: .forCreating) { success in
guard success else {
// This always fails
return
}
// Success
}
}
…but this fails with…
Error Domain=NSCocoaErrorDomain Code=513 "“<new-file-name>” couldn’t be moved because you don’t have permission to access “<folder>”."
UserInfo={NSSourceFilePathErrorKey=/private/var/mobile/Containers/Data/Application/1A9ACC2B-81EF-4EC9-940E-1C129BDB1914/tmp/(A Document Being Saved By My App)/<new-file-name>, NSUserStringVariant=( Move ), NSDestinationFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/<folder>/<new-file-name>, NSFilePath=/private/var/mobile/Containers/Data/Application/1A9ACC2B-81EF-4EC9-940E-1C129BDB1914/tmp/(A Document Being Saved By My App)/<new-file-name>, NSUnderlyingError=0x1c4e54280 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
…and just a simple move…
func renameDocument(to name: String) {
let targetURL = document.fileURL.deletingLastPathComponent().appendingPathComponent(name)
.appendingPathExtension("<extension>")
do {
try FileManager.default.moveItem(at: document.fileURL, to: targetURL)
} catch {
// This always fails
}
// Success
}
…which fails with…
Error Domain=NSCocoaErrorDomain Code=513 "“<old-file-name>” couldn’t be moved because you don’t have permission to access “<folder>”." UserInfo={NSSourceFilePathErrorKey=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/<folder>/<old-file-name>, NSUserStringVariant=( Move ), NSDestinationFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/<folder>/<new-file-name>, NSFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/<folder>/<old-file-name>, NSUnderlyingError=0x1c4c4d8c0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
Both of these work fine for local files, and renaming iCloud files works OK in the UIDocumentBrowserViewController
root view controller.
My guess is that there's some permission missing somewhere that allows the app to write to iCloud folders.
For info, the info.plist contains all the following keys…
LSSupportsOpeningDocumentsInPlace
NSExtensionFileProviderSupportsEnumeration
UISupportsDocumentBrowser
Are you doing this in the context of NSFileCoordinator
? This is required. You shouldn't need any info.plist settings apart from NSUbiquitousContainers
.
Here is my code for renaming iCloud documents:
///
/// move cloudFile within same store - show errors
///
- (void)moveCloudFile:(NSURL *)url toUrl:(NSURL *)newURL
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
NSError *coordinationError;
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
[coordinator coordinateWritingItemAtURL:url options:NSFileCoordinatorWritingForMoving
writingItemAtURL:newURL options:NSFileCoordinatorWritingForReplacing
error:&coordinationError
byAccessor:
^(NSURL *readingURL, NSURL *writingURL){
if ([self moveFile:readingURL toUrl:writingURL])
[coordinator itemAtURL:readingURL didMoveToURL:writingURL];
}];
if (coordinationError) {
MRLOG(@"Coordination error: %@", coordinationError);
[(SSApplication *)SSApplication.sharedApplication fileErrorAlert:coordinationError];
}
});
}
///
///
/// move file within same store - show errors
///
- (BOOL)moveFile:(NSURL *)url toUrl:(NSURL *)newURL
{
NSFileManager *manager = NSFileManager.defaultManager;
NSError *error;
if ([manager fileExistsAtPath:newURL.path])
[self removeFile:newURL];
if ([manager moveItemAtURL:url toURL:newURL error:&error] == NO) {
MRLOG(@"Move failed: %@", error);
[(SSApplication *)SSApplication.sharedApplication fileErrorAlert:error];
return NO;
}
return YES;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With