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