I Made a PDF an save it in my App, but I want let de user save the PDF document in a directory outside of my app. (Sorry for bad English, I am from Swiss.)
The markupTex
I am finish, that is my code
func SavePdfUser(){
    // 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)
    // save temporary for preview 
    let dateiName = "Vitalstoffwerte " + heuteString
    let fileUrl = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(dateiName).pdf")
    do {
        try pdfData.write(to: fileUrl, options: .atomic)
    } catch {
        print(error,"file not save")
    }
    // Preview
    let webview = WKWebView(frame: UIScreen.main.bounds)
    view.addSubview(webview)
    webview.load(URLRequest(url: fileUrl))
}
import UIKit import Foundation
class PdfErstellung {
static func PdfErstellen(_ auswahlZeilen : [LebensmittelDataTV], _ vitalstoffWerteListe : [LebensmittelDataTV], _ heuteString : String) {
    var y = 0 // Points from above - von oben
    var x = 0 // Points form left - von links
    var width = 0 // length of rect - länge vom rechteck
    var height = 0 // height of rect - höhe vom rechteck
    var stringRechteck = CGRect(x: x, y: y, width: width, height: height) // make rect for text - rechteck für Text
    var paragraphStyle = NSMutableParagraphStyle() // text alignment - text ausrichtung
    var font = UIFont(name: "HelveticaNeue-Bold", size: 10.0) // Important: the font name must be written correct - Wichtig: Textname muss korrekt geschrieben werden
    var text = ""
    let attributes = [
        NSAttributedString.Key.paragraphStyle: paragraphStyle,
        NSAttributedString.Key.font: font,
        NSAttributedString.Key.foregroundColor: UIColor.black
    ]
    // Title - ÜBERSCHRIFT
    font = UIFont(name: "HelveticaNeue-Bold", size: 20.0)
    text = "Tagesbedarf in % vom " + heuteString // heuteString = date/datum
    paragraphStyle.alignment = .left
    x = 50; y = 30; width = 300; height = 40
    stringRechteck = CGRect(x: x, y: y, width: width, height: height)
    text.draw(in: stringRechteck, withAttributes: attributes)
    // List - Vitalstoffwerte Liste
    y = 45
    for zeile in 0..<vitalstoffWerteListe.count {
        let druckenVitalstoffWerte = vitalstoffWerteListe[zeile]
        if druckenVitalstoffWerte.zeilenInfoID == 0 { // Title - Überschrift
            y = y + 5 // distance to above becaus is title - Abstand nach oben, weil Überschrift
            x = 50; width = 80; height = 20
            stringRechteck = CGRect(x: x, y: y, width: width, height: height)
            font = UIFont(name: "HelveticaNeue-Bold", size: 10.0) // change font - verändere schrift
            text = druckenVitalstoffWerte.name
            text.draw(in: stringRechteck, withAttributes: attributes)
            font = UIFont(name: "HelveticaNeue", size: 8.0) // change font back - schrift zurück ändern
        } else { // or detail
            x = 50; width = 90; height = 20
            stringRechteck = CGRect(x: x, y: y, width: width, height: height)
            text = druckenVitalstoffWerte.name
            text.draw(in: stringRechteck, withAttributes: attributes)
            x = 150; width = 40
            stringRechteck = CGRect(x: x, y: y, width: width, height: height)
            text = druckenVitalstoffWerte.anzahl
            paragraphStyle.alignment = .right
            text.draw(in: stringRechteck, withAttributes: attributes)
            paragraphStyle.alignment = .left
            x = 195; width = 20
            stringRechteck = CGRect(x: x, y: y, width: width, height: height)
            text = druckenVitalstoffWerte.masse
            text.draw(in: stringRechteck, withAttributes: attributes)
        }
        y = y + 10 // 10 down for next line - 10 nach unten für nächste Zeile
    }
    // Title - Überschrift
    x = 220; y = 50; width = 100; height = 20
    text = "Lebensmittel"
    font = UIFont(name: "HelveticaNeue-Bold", size: 8.0)
    paragraphStyle.alignment = .left
    stringRechteck = CGRect(x: x, y: y, width: width, height: height)
    text.draw(in: stringRechteck, withAttributes: attributes)
    font = UIFont(name: "HelveticaNeue", size: 8.0)
    // List - Lebensmittelliste
    y = 60
    for zeile in 0..<auswahlZeilen.count {
        let auswahlZeilenObjekt = auswahlZeilen[zeile]
        x = 220; width = 90; height = 20
        stringRechteck = CGRect(x: x, y: y, width: width, height: height)
        text = auswahlZeilenObjekt.name
        text.draw(in: stringRechteck, withAttributes: attributes)
        x = 320; width = 40
        stringRechteck = CGRect(x: x, y: y, width: width, height: height)
        text = auswahlZeilenObjekt.anzahl
        paragraphStyle.alignment = .right
        text.draw(in: stringRechteck, withAttributes: attributes)
        paragraphStyle.alignment = .left
        x = 365; width = 20
        stringRechteck = CGRect(x: x, y: y, width: width, height: height)
        text = auswahlZeilenObjekt.masse
        text.draw(in: stringRechteck, withAttributes: attributes)
        y = y + 10
        if zeile == 75 { // 76 items - Zeilen
            break
        }
    }
    y = 60
     if auswahlZeilen.count > 75 { // new
        for zeile in 76..<auswahlZeilen.count {
            let auswahlZeilenObjekt = auswahlZeilen[zeile]
            x = 390; width = 90; height = 20
            stringRechteck = CGRect(x: x, y: y, width: width, height: height)
            text = auswahlZeilenObjekt.name
            text.draw(in: stringRechteck, withAttributes: attributes)
            x = 490; width = 40
            stringRechteck = CGRect(x: x, y: y, width: width, height: height)
            text = auswahlZeilenObjekt.anzahl
            paragraphStyle.alignment = .right
            text.draw(in: stringRechteck, withAttributes: attributes)
            paragraphStyle.alignment = .left
            x = 535; width = 20
            stringRechteck = CGRect(x: x, y: y, width: width, height: height)
            text = auswahlZeilenObjekt.masse
            text.draw(in: stringRechteck, withAttributes: attributes)
            y = y + 10
            if zeile == 151 { // 76 items - Zeilen
                break
            }
        }
    }
}
}
-- EDIT -- The Problem ist only in IOS 12.
I do not know why, but in some simulator: I can make the file, and give the URL to UIActivityViewController and I have my own filename and in other the URL fail, and I must give the pdfData directly.
My idea: I Try first the URL and if this fail then I give the pdfData
do {
        let dateiName = "Vitalstoffwerte " + heuteString
        let fileUrl = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(dateiName).pdf")
        do {
            try pdfData.write(to: fileUrl, options: .atomic)
        } catch {
            print(error,"file not save")
        }
        let activityViewController = UIActivityViewController(activityItems: [fileUrl], applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view // für IPAD nötig
        self.present(activityViewController, animated: true, completion: nil)
    } catch {
        let activityViewController = UIActivityViewController(activityItems: [pdfData], applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view // für IPAD nötig
        self.present(activityViewController, animated: true, completion: nil)
    }
My problem ist, how I can find out, the user could save the file or not (if he had try it), can I ask the after the error code in the log? the do, catch do not go.
2018-09-25 15:36:55.787894+0200 Vitalstoffcontroller[8656:186334] [default] [ERROR] Failed to determine whether URL /Users/lukashedinger/Library/Developer/CoreSimulator/Devices/45A185C5-6DEA-4A52-B415-939758FB7F7E/data/Containers/Data/Application/2469BE4A-53B2-4545-B5D7-E64FBCDB383E/tmp/Vitalstoffwerte 25092018-25092018.pdf (n) is managed by a file provider 2018-09-25 15:36:56.312499+0200 Vitalstoffcontroller[8656:186334] [ShareSheet] cancelled request - error: The operation couldn’t be completed. Invalid argument
-- EDIT --
ma temporary solution is, in ios12 I give the data to UIActivityViewController , otherwise I save the data as file and give the url to UIActivityViewController.
     if #available(iOS 12.0, *) {
        let activityViewController = UIActivityViewController(activityItems: [pdfData], applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view // für IPAD nötig
        self.present(activityViewController, animated: true, completion: nil)
    } else {
        let dateiName = "Vitalstoffwerte " + heuteString
        let fileUrl = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(dateiName).pdf")
        do {
            try pdfData.write(to: fileUrl, options: .atomic)
        } catch {
            print(error,"file not save")
        }
        let activityViewController = UIActivityViewController(activityItems: [fileUrl], applicationActivities: nil)
        activityViewController.popoverPresentationController?.sourceView = self.view // für IPAD nötig
        self.present(activityViewController, animated: true, completion: nil)
    }