如何在Swift中为用户提供PDF数据的文件名以便保存

8

我将我的 pdfData 给用户保存。他可以将其保存为文件并制作一个文件,但是 pdf 文件的默认名称是:PDF document.pdf。如果可能的话,我想要自己的文件名。也许我可以在将 pdfData 提供给 UIActivityViewController 之前更改 pdfData 中的文件名呢?

以下是我的代码:

// Create page rect
let pageRect = CGRect(x: 0, y: 0, width: 595.28, height: 841.89) // A4, 72 dpi

// Create PDF context and draw
let pdfData = NSMutableData()

UIGraphicsBeginPDFContextToData(pdfData, pageRect, nil)
UIGraphicsBeginPDFPage()

// From here you can draw page, best make it in a function
PdfErstellung.PdfErstellen(auswahlZeilen, vitalstoffWerteListe, heuteString)

UIGraphicsEndPDFContext()

// Save pdf DATA through user
let activityViewController = UIActivityViewController(activityItems: [pdfData], applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view // für IPAD nötig
self.present(activityViewController, animated: true, completion: nil)
   

-- 更新 --

我的新想法是,首先尝试保存文件并尝试使用URL,如果失败,则直接使用pdfData,因为在某些模拟器中使用URL不会出现错误,在其他模拟器中则会出现错误。

更多信息请参见:https://stackoverflow.com/a/52499637/10392572

2个回答

29

您只需将pdfData保存到临时文件URL并共享该URL。

let temporaryFolder = FileManager.default.temporaryDirectory
let fileName = "document.pdf"
let temporaryFileURL = temporaryFolder.appendingPathComponent(fileName)
print(temporaryFileURL.path)  // /Users/lsd/Library/Developer/XCPGDevices/E2003834-07AB-4833-B206-843DC0A52967/data/Containers/Data/Application/322D1F1D-4C97-474C-9040-FE5E740D38CF/tmp/document.pdf
do {
    try pdfData.write(to: temporaryFileURL)
    // your code
    let activityViewController = UIActivityViewController(activityItems: [temporaryFileURL], applicationActivities: nil)
} catch {
    print(error)
}

我知道,但是URL不适合这个,因为它会给我这个错误: Vitalstoffcontroller[6161:165020] [default] [ERROR] Failed to determine whether URL /Users/lukashedinger/Library/Developer/CoreSimulator/Devices/4DE0F1A6-67B7-4909-8C46-78278D403E63/data/Containers/Data/Application/D72F4EE0-D330-4B2D-924E-E17FC805EF55/tmp/Vitalstoffwerte 21092018-21092018.pdf (n) is managed by a file provider. 我在这里问过了:https://stackoverflow.com/q/52457064/10392572 - Lukas Hediner
确保传递的是 URL 对象,而不是路径字符串,就像上面显示的一样。 - Leo Dabus
1
请注意,临时文件将在您的方法完成后立即被删除。 - Leo Dabus
我不想创建一个文件,因为作为数据,用户可以打印并制作PDF文件,而不仅仅是保存它。 - Lukas Hediner
@LeoDabus,你是怎么知道临时文件会被删除的?我找不到任何相关信息。我只找到了一份苹果文档,说临时文件可能会在3天后被删除。问题是我不知道应该在什么时候删除这个文件,因为没有回调来表示活动已经完成。 - soger
通常情况下,一旦方法完成并且URL超出范围,它就会被删除。 - Leo Dabus

2
请注意,您还可以设置AirDrop的用户标题,如下所示使用:
    let temporaryFolder = FileManager.default.temporaryDirectory
    let fileName = "Carburant Discount Historique des Prix au \(Date()).json"
    let temporaryFileURL = temporaryFolder.appendingPathComponent(fileName)
    print(temporaryFileURL.path)
    do {
        try? FileManager.default.removeItem(at: temporaryFileURL)

        try json.write(to: temporaryFileURL)
    }
    catch let error {
        print("\(#function): *** Error while writing json to temporary file. \(error.localizedDescription)")
        alert("Export impossible")
        return
    }

    /// Sets the **title** along with the URL
    let dataToShare: [Any] = ["Historique des prix", temporaryFileURL]

    let activityViewController = UIActivityViewController(activityItems: dataToShare, applicationActivities: nil)

1
我遇到了一个错误,直到我更改了这行代码: try json.write... 现在改为: try json.write(to: temporaryFileURL, atomically: true, encoding: .utf8) - Mattman85208
不需要删除文件,您可以直接使用原子写入选项。 - Leo Dabus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接