问题描述
我制作了一个 PDF 并将其保存在我的应用程序中,但我想让用户将 PDF 文档保存在我的应用程序外部的目录中.(抱歉英语不好,我来自瑞士.)
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 markupText in the formatter, ist this something important, that I must use for something?
我认为 - UIGraphicsBeginPDFContextToFile(pathForPDF, rect, nil) - 将文件保存在我的应用程序的文档目录中,对吗?
I think - UIGraphicsBeginPDFContextToFile(pathForPDF, rect, nil) - save the file in the document directory of my app, ist this correct?
其他问题.我的代码中是否有任何错误.我从这里的答案中提取了很多代码,希望我能做对.
Other question. Ist there any mistake in my code. I have taken a lot of code from answers here and hope that im make it right.
import UIKit
import Foundation
class PdfErstellung {
static func PdfErstellen(_ auswahlZeilen : [LebensmittelDataTV], _ vitalstoffWerteListe : [LebensmittelDataTV], _ heuteString : String) {
var html = "<html><head><meta charset='UTF-8'></head><body>Erstelle Vitalstoffwerte PDF</body></html"
// 1. Create Print Formatter with input text.
let formatter = UIMarkupTextPrintFormatter(markupText: html)
// 2. Add formatter with pageRender
let render = UIPrintPageRenderer()
render.addPrintFormatter(formatter, startingAtPageAt: 0)
// 3. Assign paperRect and printableRect
let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
let printable = page.insetBy(dx: 0, dy: 0)
let rect = CGRect.zero
render.setValue(NSValue(cgRect: page), forKey: "paperRect")
render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
// 4. Create PDF context and draw
let fileName = "Vitalstoffwerte " + heuteString
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
let pathForPDF = documentsDirectory.appendingFormat("/" + fileName)
UIGraphicsBeginPDFContextToFile(pathForPDF, rect, nil)
// Start Draw of page
var y = 0
var stringRechteckX50 = CGRect(x: 50, y: y, width: 100, height: 20)
var stringRechteckX160 = CGRect(x: 160, y: y, width: 30, height: 20)
var stringRechteckX170 = CGRect(x: 170, y: y, width: 10, height: 20)
var stringRechteckX220 = CGRect(x: 220, y: y, width: 100, height: 20)
var stringRechteckX330 = CGRect(x: 330, y: y, width: 30, height: 20)
var stringRechteckX340 = CGRect(x: 340, y: y, width: 10, height: 20)
var paragraphStyle = NSMutableParagraphStyle()
var font = UIFont(name: "Helvetica Bold", size: 20.0)
var text = ""
let attributes = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: font,
NSAttributedString.Key.foregroundColor: UIColor.black
]
var attributedString = NSAttributedString(string: text, attributes: attributes)
// ÜBERSCHRIFT
font = UIFont(name: "Helvetica Bold", size: 20.0)
text = "Tagesbedarf in % vom " + heuteString
paragraphStyle.alignment = .left
var stringRechteck = CGRect(x: 50, y: 50, width: 300, height: 40)
attributedString.draw(in: stringRechteck)
// Vitalstoffwerte Liste
y = 80
for zeile in 0..<vitalstoffWerteListe.count {
let druckenVitalstoffWerte = vitalstoffWerteListe[zeile]
if druckenVitalstoffWerte.zeilenInfoID == 0 { // Überschrift
y = y + 10
font = UIFont(name: "Helvetica Bold", size: 14.0)
text = druckenVitalstoffWerte.name
attributedString.draw(in: stringRechteckX50)
} else { // Detail
font = UIFont(name: "Helvetica", size: 12.0)
text = druckenVitalstoffWerte.name
attributedString.draw(in: stringRechteckX50)
text = druckenVitalstoffWerte.anzahl
paragraphStyle.alignment = .right
attributedString.draw(in: stringRechteckX160)
text = druckenVitalstoffWerte.masse
paragraphStyle.alignment = .left
attributedString.draw(in: stringRechteckX170)
}
y = y + 30
}
y = 80
text = "Lebensmittel"
font = UIFont(name: "Helvetica Bold", size: 14.0)
paragraphStyle.alignment = .left
attributedString.draw(in: stringRechteckX220)
// Lebensmittelliste
y = 120
for zeile in 0..<auswahlZeilen.count {
let auswahlZeilenObjekt = auswahlZeilen[zeile]
font = UIFont(name: "Helvetica", size: 12.0)
text = auswahlZeilenObjekt.name
attributedString.draw(in: stringRechteckX220)
text = auswahlZeilenObjekt.anzahl
paragraphStyle.alignment = .right
attributedString.draw(in: stringRechteckX330)
text = auswahlZeilenObjekt.masse
paragraphStyle.alignment = .left
attributedString.draw(in: stringRechteckX340)
}
y = y + 30
// End Draw of page
UIGraphicsEndPDFContext()
}
// I think the Pdf was saved before, but i do not know exactly
static func savePdf(_ urlString: String, _ fileName: String) {
DispatchQueue.main.async {
let url = URL(string: urlString)
let pdfData = try? Data.init(contentsOf: url!)
let resourceDocPath = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
let pdfNameFromUrl = "YourAppName-(fileName).pdf"
let actualPath = resourceDocPath.appendingPathComponent(pdfNameFromUrl)
do {
try pdfData?.write(to: actualPath, options: .atomic)
print("pdf successfully saved!")
} catch {
print("Pdf could not be saved")
}
}
}
}
---- 编辑 -----
---- Edit -----
我改变了很多.感谢您的链接,我找到了其他链接并有了新的想法.
I have change a lot. Thanks for the link, I found other links and had new ideas.
我的下一个问题是:
Vitalstoffcontroller[6161:165020] [default] [ERROR] 无法确定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) 由文件提供商管理
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 found this, but not understand, what my mistake is.
UIActivityViewController 错误:无法确定是否URL 由文件提供者管理
如何将文件保存在文档文件夹中?
(也许是我阅读的 IOS 12 的一个错误:https://forums.developer.apple.com/thread/103198)
(Perhaps is a bug of IOS 12 I read: https://forums.developer.apple.com/thread/103198)
我的新代码
// 5. Save PDF file
let dateiName = "Vitalstoffwerte " + heuteString
let path = "(NSTemporaryDirectory())(dateiName).pdf"
pdfData.write( toFile: path, atomically: true)
print("open (path)")
// var fileUrl: URL = URL(fileURLWithPath: NSTemporaryDirectory())
// fileUrl.appendPathComponent("foo")
// fileUrl.appendPathExtension("bar")
let fileUrl: URL = URL(fileURLWithPath: path)
let directory = "(NSTemporaryDirectory())"
let directoryUrl : URL = URL(fileURLWithPath: directory)
print("open (fileUrl)")
print("open (directoryUrl)")
let fm = FileManager.default
//let fileName = String((fileUrl.lastPathComponent)) as NSString
//let documentsUrl:URL = fm.urls(for: .documentDirectory, in: .userDomainMask).first!
//let destinationFileUrl = documentsUrl.appendingPathComponent("(fileName)")
//print("open (documentsUrl)")
//do {
// try fm.removeItem(at: destinationFileUrl)
/