无法通过打开方式 <My App> 共享 sheet 从 iOS 文件应用程序打开文件:提供的文件 URL 中不存在任何文件

Cannot open file from iOS Files app via the Open In <My App> share sheet: no file at the provided file URL exists

我的 iOS 应用程序可以打开 CSV 文件,以便导入他们的数据。我可以通过 UIDocumentPickerViewController 从应用程序中打开文件,没有任何问题,选择文件应用程序中显示的文件。但是,当首先在“文件”应用程序中查看文件,然后从那里打开我的应用程序(通过“打开方式”共享 sheet)时,我的应用程序无法在 URL 处看到传递给我的应用程序的文件。该文件似乎不存在。

我将以下调试代码添加到我的 AppDelegate 中:

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    print("Exists: \(FileManager.default.fileExists(atPath: url.path)) (\(url.path))")
    return true
}

当我在此应用程序的文件中打开文件时,会生成如下日志行:

Exists: false (/private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/Reading List - Andrew’s iPhone - 2018-10-18 11-19.csv)

当我从其他应用程序(例如 Dropbox 或电子邮件)打开文件时,文件 可以 被处理,并记录以下内容:

Exists: true (/private/var/mobile/Containers/Data/Application/F9110F90-7A91-4AB6-A92E-0ED933184EA4/Documents/Inbox/Reading List - Andrew’s iPhone - 2018-01-27 08-03.csv)

注意不同的路径(Documents/InboxMobile Documents/com~apple~CloudDocs)。是什么原因造成的?如何在我的应用程序中支持从“文件”应用程序打开文件?

我的应用支持的文档类型如下:

我认为您不能在不同的应用程序(不在同一个应用程序组中)之间共享文件:

我通过调整应用 Info.plist 中的一些设置解决了这个问题。

我把UISupportsDocumentBrowser改成了false,又加了LSSupportsOpeningDocumentsInPlace,也改成了false

在收到来自 App Store Connect 的电子邮件后,我认为这些设置(由我)设置不正确:

Invalid Document Configuration - Document Based Apps should support either the Document Browser (UISupportsDocumentBrowser = YES) or implement Open In Place (LSSupportsOpeningDocumentsInPlace = YES/NO). Visit https://developer.apple.com/document-based-apps/ for more information.

LSSupportsOpeningDocumentsInPlace 标志设置为 false 可防止在文件应用程序中选择文件时自动打开该应用程序。如果文件在需要的地方打开,首先需要 request/unlock 访问:

 func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {     
   let opensInPlace = options[.openInPlace] != nil
   opensInPlace ? url.startAccessingSecurityScopedResource() : nil
   let fileExists = FileManager.default.fileExists(atPath: url.path)  
   opensInPlace ? url.stopAccessingSecurityScopedResource() : nil
 }