8

I give my pdfData to user to save. He can save to files and make a file, but the default name of the pdf file is: PDF document.pdf. I want my own filename if this is possible. Perhaps I can change the filename within the pdfData before I give pdfData to UIActivityViewController?

Here is my code:

// 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)
   

-- UPDATE --

My new idea ist, first try save the file and try a URL, and if this fail, then use the pdfData directly, because in some simulator use URL give no error and in other give error.

More here: https://stackoverflow.com/a/52499637/10392572

pawello2222
  • 46,897
  • 22
  • 145
  • 209
Lukas Hediner
  • 127
  • 3
  • 6

2 Answers2

29

You just need to save your pdfData to a temporary fileURL and share that 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)
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • I know, but a url is not good for that because it give me this error: 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. I asked about that here: https://stackoverflow.com/q/52457064/10392572 – Lukas Hediner Sep 23 '18 at 15:29
  • Make sure you pass the url object not a path string exactly as shown above – Leo Dabus Sep 23 '18 at 15:58
  • 1
    Note that the temporary file will be deleted as soon as your method finishes – Leo Dabus Sep 23 '18 at 15:59
  • I do not want make a file, because as data, user can print and make pdf with my data, not only save it – Lukas Hediner Sep 24 '18 at 10:36
  • @LeoDabus how do you know the temp file will be deleted? I can't find any info on this. I found only one apple document that says the temp file may be deleted after 3 days. The problem is I can't find out when I should delete the file, there's no callback when the activity is finished. – soger Apr 11 '22 at 14:21
  • Usually it is deleted as soon as the method finishes and the url gets out of scope – Leo Dabus Apr 11 '22 at 14:42
2

Note that you can also set a user title for AirDrop to be used as follows:

    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)
Stéphane de Luca
  • 12,745
  • 9
  • 57
  • 95