2017-10-02 1 views
5

Ich habe Schwierigkeiten herauszufinden, wie ich eine Instanz einer UIDocument Unterklasse in einem iCloud-Ordner umbenennen kann. Ich habe versucht, das Dokument mit der neuen URL-Speicher ...Ein UIDocument in iCloud umbenennen

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 
    } 
} 

... aber irgendwie ...

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"}}

... und nur eine einfache Bewegung ...

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 
} 

... was fehlschlägt w ith ...

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"}}

Diese beiden arbeiten gut für lokale Dateien und Dateien iCloud Umbenennung funktioniert OK in der UIDocumentBrowserViewController Root-View-Controller.

Meine Vermutung ist, dass irgendwo eine Erlaubnis fehlt, die es der App erlaubt, in iCloud-Ordner zu schreiben.

Für Informationen, die info.plist enthält alle folgenden Tasten ...

  • LSSupportsOpeningDocumentsInPlace
  • NSExtensionFileProviderSupportsEnumeration
  • UISupportsDocumentBrowser
+0

Ist das Dokument geöffnet, wenn Sie versuchen, es zu benennen? – theMikeSwan

+0

Es scheint keinen Unterschied zu machen, ob es offen oder geschlossen ist. –

+0

Schauen Sie sich https://developer.apple.com/documentation/foundation/filemanager/1413989-setubiquitous an, ob das hilft. Ich bin mir ziemlich sicher, dass einige der normalen Dateimanager-Methoden im iCloud-Container nicht funktionieren (obwohl iOS 11 die Dinge vielleicht geändert hat ...) – theMikeSwan

Antwort

1

Tun Sie dies im Zusammenhang mit der NSFileCoordinator? Dies ist erforderlich. Abgesehen von NSUbiquitousContainers sollten Sie keine Einstellungen für info.plist benötigen.

Hier ist mein Code für die Umbenennung iCloud Dokumente:

/// 
/// 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; 
} 
+0

Schön zu sehen, welche Möglichkeiten jemand anderes dazu benutzt hat. Viel besser als das, was ich benutzte. Aber ich dachte, Sie sollten nicht den Standard-Dateimanager in einem Koordinator verwenden. – Sojourner9

Verwandte Themen