Estoy tratando de convertir el contenido de un WKWebView a un archivo PDF.
Antes de que UIWebView en desuso, se hacía de esta manera:
webView.loadHTMLString("<h1>HELLO!</h1>", baseURL: nil) let pdfData = webView.mainFrame.frameView.documentView.dataWithPDF(inside: webView.mainFrame.frameView.documentView.frame) let document = PDFDocument(data: pdfData)Lo que probé ahora:
webView.loadHTMLString("<h1>HELLO!</h1>", baseURL: nil) let pdfData = self.webViewPDF.webFrame.frameView.documentView.dataWithPDF(inside: self.webViewPDF.webFrame.frameView.documentView.frame) let document = PDFDocument(data: pdfData)pero obtuve el siguiente error en su lugar:
[WKWebView webFrame]: selector no reconocido enviado a la instancia.
[General] Se generó una excepción no detectada
El problema es que WKWebView no tiene la propiedad mainFrame ...
Actualizar La solución a continuación funciona muy bien en iOS , pero ahora me di cuenta de que está buscando una solución para macOS . Por favor, hágame saber si esta solución podría ser de alguna ayuda... perdón por la confusión;)
Ahora puede usar el método UIView.viewPrintFormatter() (de la clase UIView ) para eso:
Devuelve un formateador de impresión para la vista de recepción.
Al iniciar un trabajo de impresión, puede llamar a este método para obtener un objeto formateador de impresión de vista apropiado para su vista. Puede usar el objeto formateador para configurar las opciones de diseño de página para su vista durante la impresión.
Por ejemplo:
import UIKit import WebKit import PDFKit extension WKWebView { /// Exports a PDF document with this web view current contents. /// Only call this function when the web view has **finished** loading. func exportAsPDF() -> PDFDocument? { guard self.isLoading == false else { print("WKWebView still loading!") return nil } let pdfData = createPDFData() return PDFDocument(data: pdfData) } private func createPDFData() -> Data { let oldBounds = self.bounds var printBounds = self.bounds printBounds.size.height = scrollView.contentSize.height self.bounds = printBounds var printableRect = printBounds printableRect.origin = .zero let printRenderer = UIPrintPageRenderer() printRenderer.addPrintFormatter(self.viewPrintFormatter(), startingAtPageAt: 0) printRenderer.setValue(NSValue(cgRect: UIScreen.main.bounds), forKey: "paperRect") printRenderer.setValue(NSValue(cgRect: printableRect), forKey: "printableRect") self.bounds = oldBounds return printRenderer.generatePDFData() } } y agregue el siguiente método auxiliar a UIPrintPageRenderer también:
extension UIPrintPageRenderer { func generatePDFData() -> Data { let pdfData = NSMutableData() UIGraphicsBeginPDFContextToData(pdfData, self.paperRect, nil) self.prepare(forDrawingPages: NSMakeRange(0, self.numberOfPages)) let printRect = UIGraphicsGetPDFContextBounds() for pdfPage in 0..<self.numberOfPages { UIGraphicsBeginPDFPage() self.drawPage(at: pdfPage, in: printRect) } UIGraphicsEndPDFContext() return pdfData as Data } } Finalmente, ahora puede guardar un PDF usando la API exportAsPDF() definida anteriormente:
let webView: WKWebView = ... let pdfDocument = webView.exportAsPDF()! let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let pdfFile = docsDir.appendingPathComponent("WebViewPDF.pdf") try! pdfDocument.write(to: pdfFile)