为什么 url.bookmarkData 返回零?
Why is url.bookmarkData returning nil?
我们有一个 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)
}
一切正常,我们可以 select 一个文档。当我们 select 一个文档时,我们得到一个文档 url 但在某些情况下(尤其是在一个驱动器上),当我们想要将 url 变成书签时会遇到问题。以下代码 returns nil:
guard let bookmark = try? url.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil) else { return }
有人知道为什么会这样吗?或者我们可以做些什么来让它在没有 returning nil 的情况下工作?
编辑:
我们已尝试添加 try catch,但出现了以下错误,但没有太大帮助:Error Domain=NSCocoaErrorDomain Code=260
(文件不存在)。
编辑 2:
因此,如果我直接从存档中打开到我们的应用程序,则完全没有问题。但是我们仍然需要从 UIDocumentPickerViewController 开始工作。
此外,出于某些原因,以这种方式解锁的文件之后将只能在 UIDocumentPickerViewController 中使用。
文件也可以从 onedrive 打开,然后在另一个应用程序(我们的)中打开。但这并没有给出文件不存在的错误。
编辑 3:
所以我已经测试并阅读了大量内容。我可以看出,对于 documentpicker 选择的某些文件,以下内容 return 为 false:
var exist = FileManager.default.fileExists(atPath: url.path)
但是,如果我只从 iOS 存档应用程序打开文件一次,它将在之后完美运行。如果有某种方法可以像苹果那样告诉它 update/download。
编辑 4:
我在 github 做了一个示例项目来演示这个问题。
我在这里回答了一个类似的问题:
你能检查一下将你的 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
使用了 apple 的技术票,他们提供了解决方案 :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)
}
我们有一个 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)
}
一切正常,我们可以 select 一个文档。当我们 select 一个文档时,我们得到一个文档 url 但在某些情况下(尤其是在一个驱动器上),当我们想要将 url 变成书签时会遇到问题。以下代码 returns nil:
guard let bookmark = try? url.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil) else { return }
有人知道为什么会这样吗?或者我们可以做些什么来让它在没有 returning nil 的情况下工作?
编辑:
我们已尝试添加 try catch,但出现了以下错误,但没有太大帮助:Error Domain=NSCocoaErrorDomain Code=260
(文件不存在)。
编辑 2:
因此,如果我直接从存档中打开到我们的应用程序,则完全没有问题。但是我们仍然需要从 UIDocumentPickerViewController 开始工作。
此外,出于某些原因,以这种方式解锁的文件之后将只能在 UIDocumentPickerViewController 中使用。
文件也可以从 onedrive 打开,然后在另一个应用程序(我们的)中打开。但这并没有给出文件不存在的错误。
编辑 3: 所以我已经测试并阅读了大量内容。我可以看出,对于 documentpicker 选择的某些文件,以下内容 return 为 false:
var exist = FileManager.default.fileExists(atPath: url.path)
但是,如果我只从 iOS 存档应用程序打开文件一次,它将在之后完美运行。如果有某种方法可以像苹果那样告诉它 update/download。
编辑 4: 我在 github 做了一个示例项目来演示这个问题。
我在这里回答了一个类似的问题:
你能检查一下将你的 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
使用了 apple 的技术票,他们提供了解决方案 :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)
}