【问题标题】:Renaming a UIDocument in iCloud在 iCloud 中重命名 UIDocument
【发布时间】:2018-03-13 14:04:14
【问题描述】:

我正在努力弄清楚如何在 iCloud 文件夹中重命名 UIDocument 子类的实例。我已尝试使用新 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
    }
}

…但这失败了…

Error Domain=NSCocoaErrorDomain Code=513 "“&lt;new-file-name&gt;” couldn’t be moved because you don’t have permission to access “&lt;folder&gt;”." 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
}

…失败了…

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

【问题讨论】:

  • 在您尝试重命名时文档是否打开?
  • 打开还是关闭似乎没有任何区别。
  • 看看developer.apple.com/documentation/foundation/filemanager/… 看看是否有帮助。我很确定一些普通的文件管理器方法在 iCloud 容器中不起作用(尽管 iOS 11 可能已经改变了一些东西……)
  • 我会再看一遍。我以前的 iOS 10 版本使用该方法工作,但我的印象是 iOS 11 中的情况发生了变化,因为您可以将文件保存到任何位置,在这种情况下,您如何知道它是 iCloud 还是本地文件夹...或其他位置?
  • 这可能是苹果错过的那些地方之一,假设任何重命名都会发生在他们闪亮的新文档浏览器中。我已经对浏览器进行了一些试验,但还不足以找到粗糙的边缘(除了需要让 info.plist 的东西完全正确地工作)。

标签: ios icloud ios11 uidocument


【解决方案1】:

您是在NSFileCoordinator 的上下文中执行此操作吗?这是必需的。除了NSUbiquitousContainers,您不需要任何 info.plist 设置。

这是我重命名 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;
}

【讨论】:

  • 很高兴看到其他人用来执行此操作的选项。比我用的好多了。但我认为你不要在协调器中使用默认的 FileManager。
【解决方案2】:

NSDestinationFilePath=/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/&lt;folder&gt;/&lt;new-file-name&gt;

您正在尝试将文档保存在沙盒之外。你只能在你自己的容器中写入文件,所以没有办法做你想做的事。如果您希望 API 重命名当前文件,请在 bugreport.apple.com 提交错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    • 2014-11-18
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    相关资源
    最近更新 更多