如何在 UIDocumentInteractionController 中打开内存不足的文件?

How can I open a file out of memory in a UIDocumentInteractionController?

我们不允许永久存储文件,但允许客户自行决定是否要将其保存在其他 app/send 某处。听起来像是 UIDocumentInteractionController 的工作,但没有持久性部分。

Apple 在文档中指出:

"[…]you can use a document interaction controller with a file that was synced to your app’s Documents/Shared directory."

是否可以直接打开文件而不将其作为文件存储在 UIDocumentInteractionController 中?

我们已经将 PDF/图像作为数据。有没有办法将数据编码为 URL 并使用它来打开交互控制器?

这个不行,只能分享本地资源。

您可以做的是将文件保存在临时文件夹中并访问它。以下是如何实现此目的的代码。查看说明的评论:

import UIKit

class ViewController: UIViewController {
    let sharingController = UIDocumentInteractionController()
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if let pdfURL = Bundle.main.url(forResource: "yourPDF", withExtension: "pdf") {
            do {
                let pdfData = try Data(contentsOf: pdfURL)
                // create a destination url to save your pdf data
                let destURL = FileManager.default.temporaryDirectory.appendingPathComponent("tempFile.pdf")
                // write your pdf data to the destinastion url
                do {
                    try pdfData.write(to: destURL)
                    // share your url using UIDocumentInteractionController
                    shareURL(url: destURL)
                } catch {
                    print(error)
                }
            } catch {
                print(error)
            }
        }
        
    }
    func shareURL(url: URL){
        sharingController.url = url
        sharingController.uti = "public.data, public.content"
        sharingController.name = url.lastPathComponent
        sharingController.presentOptionsMenu(from: view.frame, in: view, animated: true)
    }
}

也没有必要删除该文件,因为它位于临时目录中。

尝试使用,

    import UIKit
    import QuickLook
    class YourViewController:UIViewController,QLPreviewControllerDataSource, QLPreviewControllerDelegate {

       func openFile(){

        let objURL = "file URL "
        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
        let url = URL(fileURLWithPath: path)
        let theFileName = (objURL as NSString).lastPathComponent
        let filePath = url.appendingPathComponent("\(theFileName)").path
        let fileManager = FileManager.default
        if fileManager.fileExists(atPath: filePath) {
            print("FILE AVAILABLE")
            self.pathString = filePath
            let viewPDF = QLPreviewController()
            viewPDF.dataSource = self
            viewPDF.delegate = self
            self.item.previewItemTitle = self.previewFileTitle
            self.item.previewItemURL = URL.init(fileURLWithPath: filePath)
            self.present(viewPDF, animated: true, completion: nil)
        } else {
            print("FILE NOT AVAILABLE")
            previewFileTitle = theFileName
            self.downloadPDF(objURL)
        }


    }

    func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
        return 1
    }

    func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {

        let url = URL(fileURLWithPath: pathString)

        return item as QLPreviewItem
    }

    func previewController(_ controller: QLPreviewController, shouldOpen url: URL, for item: QLPreviewItem) -> Bool {
        return true
    }
    func downloadPDF(_ url:String){
        let requestURL: URL = URL(string: url)!
        let urlRequest: URLRequest = URLRequest(url: requestURL)
        let task = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            if let httpResponse = response as? HTTPURLResponse {
                let statusCode = httpResponse.statusCode
                if (statusCode == 200) {
                    print("Downloaded Successfully")
                    let documentsDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
                    let sourceUrl = URL(string:url)!
                    //Get the file name and create a destination URL
                    let fileName = sourceUrl.lastPathComponent
                    let destinationURL = documentsDirectoryUrl!.appendingPathComponent(fileName)

                    //Hold this file as an NSData and write it to the new location
                    if let fileData = try? Data(contentsOf: sourceUrl) {
                        try? fileData.write(to: destinationURL, options: [])   // true
                        print(destinationURL.path)
                        self.pathString = destinationURL.path
                        let viewPDF = QLPreviewController()
                        viewPDF.dataSource = self
                        viewPDF.delegate = self
                        self.item.previewItemTitle = self.previewFileTitle
                        self.item.previewItemURL = destinationURL
                        self.present(viewPDF, animated: true, completion: nil)
                    }

                }else{
                }
            }
        }
        task.resume()

    }
}

class PreviewItem: NSObject, QLPreviewItem {
    var previewItemURL: URL?
    var previewItemTitle: String?
}

Developer documentation
See this tutorial