快速查看预览扩展 iOS preparePreviewOfFile(at:completionHandler:)

Quick Look Preview Extension iOS preparePreviewOfFile(at:completionHandler:)

我正在尝试为基于 UIDocument 的 iOS 应用程序编写一个简单的快速查看预览扩展。

问题是,在我执行 preparePreviewOfFile(at:completionHandler:) 时,我试图根据我收到的 URL 打开 UIDocument 失败。我用文件 URL 实例化我的文档并调用 open(completionHandler:) 但我没有获得任何数据,并且我看到一条控制台消息,指出文件协调器已崩溃。

所有这些在我的实际应用中都运行良好;只是 Quick Look Preview Extension 实施有问题。要从 Quick Look Preview Extension 中打开 UIDocument,我需要做些什么特别的事情吗? Apple 不提供任何示例代码;在 WWDC 2017 视频 229 中,他们只是掩盖了整个事情。

编辑: 越来越好奇了。我创建了一个简化的测试平台应用程序,它使用 UIDocumentInteractionController 显示 Quick Look 预览,以及我的自定义 Quick Look Preview 扩展。在模拟器上,预览有效!在设备上,它没有。看起来,当我告诉我的文档打开时,它的 load(fromContents:ofType) 甚至从未被调用过;相反,我们收到了一对这样的错误消息:

The connection to service named com.apple.FileCoordination was invalidated.

A process invoked one of the -[NSFileCoordinator coordinate...] methods but filecoordinationd crashed. Returning an error.

我能够通过 not 在我的 UIDocument 上调用 open 来解决这个问题。相反,我直接在后台线程上调用 read,如下所示:

func preparePreviewOfFile(at url: URL, completionHandler handler: @escaping (Error?) -> Void) {
    DispatchQueue.global(qos: .background).async {
        let doc = MyDocument(fileURL: url)
        do {
            try doc.read(from: url)
            DispatchQueue.main.async {
                // update interface here!
            }
            handler(nil)
        } catch {
            handler(error)
        }
    }
}


我什至不知道这是否合法。您可能认为直接阅读文档而不使用文件协调器是很糟糕的。但它似乎确实有效!


我找到了另一种解决方法,使用 NSFileCoordinator 并手动调用 load 来获取 UIDocument 来处理数据:

    let fc = NSFileCoordinator()
    let intent = NSFileAccessIntent.readingIntent(with: url)
    fc.coordinate(with: [intent], queue: .main) { err in
        do {
            let data = try Data(contentsOf: intent.url)
            let doc = MyDocument(fileURL: url)
            try doc.load(fromContents: data, ofType: nil)
            self.lab.text = doc.string
            handler(nil)
        } catch {
            handler(error)
        }
    }


同样,这是否合法,我不知道,但我觉得这比直接调用 read 更好,因为至少我正在通过一个文件协调器。