未下载文件时从“文件”应用程序打开文件(使用“就地打开”)

N.W*_*N.W 7 swift

我希望我的用户能够点击“文件”应用程序中的文件并将其发送到我的应用程序。以前,我已经将应用程序设置为能够在使用“打开方式”以这种方式共享文件时成功地从邮件打开文件。我使用的文件类型是我的应用程序自定义的。创建文档类型、导出的 UTI 和导入的 UTI 是为了启用“打开方式”,并且尚未更改。

如果文件尚未在“文件”应用程序中下载,我会收到错误消息(带有向下箭头的小云位于文件名旁边)。即使您长按它并选择“共享”并使用“打开方式”,我也会收到相同的错误。

如果该文件已从该设备添加到“文件”中,则该文件已经下载并在“文件”中点击它就可以正常工作。如何强制 Files 在将文件发送到我的应用程序之前下载该文件?我在网上搜索过,我能找到的唯一参考资料在这里: https: //forums.developer.apple.com/thread/47890,最后一篇文章讨论了同样的问题,但我在任何地方都找不到解决方案。

在我的 info.plist 文件中,我将应用程序设置为“支持就地打开文档”设置为“是”。我还将“应用程序支持 iTunes 文件共享”设置为“是”。

我正在检查该方法中 options[.openInPlace] 的值,application(_:open:options:)以检测该文件是否来自“文件”应用程序。url.startAccessingSecurityScopedResource()当文件已经下载到设备上时,我必须先添加调用,然后它才能工作。

这是执行处理的代码的精简版本:

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
let isOpenInPlace = options[.openInPlace] as? Bool
var securityScopedResource = false

if isOpenInPlace {
    securityScopedResource = url.startAccessingSecurityScopedResource()
}

do {
    let data = try Data(contentsOf: url)
    // Use the data to create something inside my app

    if securityScopedResource {
        url.stopAccessingSecurityScopedResource()
    }
} catch {
    print("ERROR: \(error.localizedDescription)")
    if securityScopedResource {
        url.stopAccessingSecurityScopedResource()
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

ERROR: The file <filename.ext> couldn't be opened because there is no such file
Run Code Online (Sandbox Code Playgroud)

有什么方法可以让它工作吗?或者这是文件的问题吗?

(我正在使用 XCode 10.3 和 swift 5,并在真实设备上进行测试:带有 iOS 11.4 的 iPhone 6 和带有 iOS 12.1 的 iPadPro)

8 月 18 日编辑添加:

经过进一步研究,我发现我需要请求从我的应用程序中下载该文件。当我检测到 open in place = true 并且该文件尚不存在时,我已将以下内容添加到我的代码中:

try FileManager.default.startDownloadingUbiquitousItem(at: url)
Run Code Online (Sandbox Code Playgroud)

此方法开始下载,但它是异步的并立即返回。我正在尝试找出一种可靠的方法来开始下载,并等到下载完成后再进入应用程序中的下一步。任何帮助,将不胜感激!