【问题标题】:Why is url.bookmarkData returning nil?为什么 url.bookmarkData 返回 nil?
【发布时间】:2021-12-03 13:50:47
【问题描述】:

我们有一个 UIDocumentPickerViewController 的实现,看起来像这样:

case .openInitialization:
    // Setup UIDocumentPicker.
    if #available(iOS 14, *) {
        documentsPicker = UIDocumentPickerViewController(forOpeningContentTypes: [
            UTType.text,
            UTType.utf8PlainText,
            UTType.flatRTFD,
            UTType.pdf])
    } else {
        documentsPicker = UIDocumentPickerViewController(documentTypes: [
            String(kUTTypeText),
            String(kUTTypeUTF8PlainText),
            String(kUTTypeFlatRTFD),
            String(kUTTypePDF)], in: .open)
    }

一切都很好,我们可以选择一个文档。当我们选择一个文档时,我们会得到一个文档 url,但在某些情况下(尤其是使用一个驱动器),当我们想要将 url 转换为书签时会遇到问题。以下代码返回 nil:

guard let bookmark = try? url.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil) else { return }

有人知道为什么会这样吗?或者我们可以做些什么来让它在不返回 nil 的情况下工作?

编辑

我们尝试添加 try catch,但出现以下错误,但并没有多大帮助:Error Domain=NSCocoaErrorDomain Code=260(文件不存在)。

编辑 2

因此,如果我从存档直接打开到我们的应用程序,它完全没有问题。但是我们仍然需要从 UIDocumentPickerViewController 工作。

由于某些原因,以这种方式解锁的文件之后只能在 UIDocumentPickerViewController 中工作。

文件也可以从一个驱动器打开,然后在另一个应用程序(我们的)中打开。但这不会,并且也会给出文件不存在错误。

编辑 3: 所以我已经测试并阅读了很多。我可以说,对于 documentpicker 选择的某些文件,以下内容将返回 false:

var exist = FileManager.default.fileExists(atPath: url.path)

但是,如果我只从 iOS 归档应用程序中打开文件一次,之后它会完全正常工作。如果有某种方法可以告诉它像苹果一样更新/下载。

编辑 4: 我在github 做了一个示例项目来演示这个问题。

【问题讨论】:

  • 如果你不使用try?,但使用do/catch,可能会抛出一个错误,解释原因...
  • @Larme 实际上我们已经尝试过了。我忘了提供该信息更新错误代码 2 秒。
  • 你可以为每个不同的提供者调试这个并获得一组 url 来手动测试这个吗?
  • @brandonscript 嗯,这周我会尝试深入研究它,看看我发现了什么。

标签: ios file-handling


【解决方案1】:

使用了苹果的技术票,他们提供了一个解决方案:D

NSFileCoordinator().coordinate(readingItemAt: url, options: .withoutChanges, error:&err, byAccessor: { (newURL: URL) -> Void in
  do {
    let bookmark = try newURL.bookmarkData()
  } catch let error {
    print("\(error)")
  }
})

if let err = err {
  print(err.localizedDescription)
}

【讨论】:

  • 不错的一个!我以前从未听说过。我总是忘记那些苹果技术票。谢谢分享!!
【解决方案2】:

我在这里回答了类似的问题:PDFKit doesn’t work on iPads while works fine on a simulator [iOS, Swift]

您能否检查将您的 url 包装在安全访问范围内是否有帮助?:

url.startAccessingSecurityScopedResource()
print(FileManager.default.fileExists(atPath: url.path))
url.stopAccessingSecurityScopedResource()

上面应该打印正确。这是因为这些 API 在应用程序沙箱之外访问文件。

见:https://developer.apple.com/documentation/uikit/view_controllers/providing_access_to_directories

【讨论】:

  • 我确实试过了,但文件不存在。但它显然是存在和存在的。如果我通过存档打开它就可以了。
  • 抱歉提供虚假信息。你能把一个示例项目放在github上吗?我现在很忙,但有兴趣在未来看看我是否能解决这个问题。
  • 我可以试试看能不能做一个样例项目。消除所有其他噪音以确保我没有遗漏任何东西会很好。不过给我一些时间;)
  • 抱歉耽搁了 Rufus:github.com/vitec-mv/iosdocpicker
  • 显然我们需要用 NSFileCoordinator 封装对书签的调用。我添加了苹果从技术工单中得出的答案。
猜你喜欢
  • 2014-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 2011-06-26
  • 2015-08-30
相关资源
最近更新 更多