Rename UIDocument to iCloud

I am trying to figure out how to rename an instance of a subclass of UIDocument in an iCloud folder. I tried to save the document with a 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 is not 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 step ...

 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 does not work 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 features are great for local files, and renaming iCloud files works fine in the UIDocumentBrowserViewController root view UIDocumentBrowserViewController .

My guess is that somewhere there is some kind of permission that allows the application to write to iCloud folders.

For information info.plist contains all of the following keys ...

  • LSSupportsOpeningDocumentsInPlace
  • NSExtensionFileProviderSupportsEnumeration
  • UISupportsDocumentBrowser
+5
source share
1 answer

Are you doing this in the context of NSFileCoordinator ? It's necessary. You do not need any NSUbiquitousContainers settings other than 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; } 
+1
source

Source: https://habr.com/ru/post/1272282/


All Articles