QLPreviewControllerDelegate 的方法 didSaveEditedCopyOf 被调用 URL 没有内容

QLPreviewControllerDelegate's method didSaveEditedCopyOf gets called with URL that has no content

我正在使用 QLPreviewController 来显示不同类型的文档。所有这些文档都可以通过返回 QLPreviewItemEditingMode.createCopyQLPreviewItemEditingMode.updateContentsQLPreviewControllerDelegatepreviewController(_:editingModeFor:) 实例方法来编辑。

使用 QLPreviewItemEditingMode.updateContents 时一切正常。当用户编辑文档 previewController(_:didUpdateContentsOf:) 时,QLPreviewControllerDelegate 的方法被调用,并且可以使用传递到 QLPreviewController 的数据源的 url 访问更新的内容。

当我想使用 QLPreviewItemEditingMode.createCopy 时问题就出现了。当用户停止编辑文档时,QLPreviewControllerDelegatepreviewController(_:didSaveEditedCopyOf:at:) 方法将使用 URL 类型的 modifiedContentsURL 参数调用。第一次调用此方法时,我从 modifiedContentsURL 读取数据并成功检索到它。但是在第一个调用返回 url 之后的所有其他调用都没有要检索的数据。

符合QLPreviewControllerDelegate协议的对象如下所示:

final class CustomQLPreviewDelegate: NSObject, QLPreviewControllerDelegate {
    
    var onSave: ( (Data?) -> Void )?
    
    func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode {
        .createCopy
    }
    
    func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: QLPreviewItem, at modifiedContentsURL: URL) {
        
        // nil everytime after the first call
        let data = try? Data(contentsOf: modifiedContentsURL)
        
        onSave?(data)
    }
    
}

I also inspected edited document in Finder and its edited copy is generated after the first call, then removed after the second call and never created again in subsequent calls.

我只是想在将此作为错误报告给 Apple 之前确保我所做的一切都是正确的。

根据 @Leo Dabus 的建议,我尝试 将文件从 modifiedContentsURL 复制 到其他目录。项目被第一次复制,然后就再也没有复制过。

然后我尝试modifiedContentsURL 移动 文件,这成功了。每次调用 previewController(_:didSaveEditedCopyOf:at:) 后,文件都已成功移动。这是我的 CustomQLPreviewDelegate class:

的重写代码
final class CustomQLPreviewDelegate: NSObject, QLPreviewControllerDelegate {
    
    var onSave: ( (URL) -> Void )?
    let directoryUrlForEditedCopies: URL
    
    init(directoryUrlForEditedCopies: URL) {
        self.directoryUrlForEditedCopies = directoryUrlForEditedCopies
        super.init()
    }
    
    func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode {
        .createCopy
    }
    
    func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: QLPreviewItem, at modifiedContentsURL: URL) {
        
        // Get the extension of current edited file
        let fileExtension = modifiedContentsURL.pathExtension
        guard !fileExtension.isEmpty else { return }
        
        // Create destination url for moving the file
        let dstUrl = createUrl(withFileExtension: fileExtension)
        
        // Move edited copy from temporary location
        // and call onSave closure with destination url
        let error = moveEditedCopy(at: modifiedContentsURL, to: dstUrl)
        guard error == nil else { return }
        onSave?(dstUrl)
    }
    
    private func moveEditedCopy(at srcUrl: URL, to dstUrl: URL) -> Error? {
        do {
            try FileManager.default.moveItem(at: srcUrl, to: dstUrl)
            return nil
        } catch (let error) {
            return error
        }
    }
    
    func createUrl(withFileExtension fileExtension: String) -> URL {
        let randomFileName = UUID().uuidString
        return directoryUrlForEditedCopies.appendingPathComponent(randomFileName, isDirectory: false).appendingPathExtension(fileExtension)
    }
}