在iCloud中重命名UIDocument

Ash*_*lls 6 ios icloud uidocument ios11

我正在努力弄清楚如何UIDocument在iCloud文件夹中重命名子类的实例.我尝试使用新网址保存文档...

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
    }
}
Run Code Online (Sandbox Code Playgroud)

......但这失败了......

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

......而且只是一个简单的举动......

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
}
Run Code Online (Sandbox Code Playgroud)

......失败了......

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

这两种方法都适用于本地文件,并且重命名iCloud文件在UIDocumentBrowserViewController根视图控制器中可以正常工作.

我的猜测是,某些允许应用程序写入iCloud文件夹的权限丢失了.

有关信息,info.plist包含以下所有键...

  • LSSupportsOpeningDocumentsInPlace
  • NSExtensionFileProviderSupportsEnumeration
  • UISupportsDocumentBrowser

Mic*_*rke 2

您是在以下背景下这样做的吗NSFileCoordinator?这是必需的。除了 之外,您不需要任何 info.plist 设置NSUbiquitousContainers

这是我重命名 iCloud 文档的代码:

///
/// 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;
}
Run Code Online (Sandbox Code Playgroud)