2016-07-04 62 views
5

Sto cercando di capire come salvare una WebView in un PDF e completamente bloccato, apprezzerebbe davvero qualche aiuto?Salvataggio di WebView in PDF restituisce un'immagine vuota?

sto facendo questo a Cocoa & Swift su OSX, ecco il mio codice finora:

import Cocoa 
import WebKit 

class ViewController: NSViewController { 

    override func loadView() { 
     super.loadView() 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     loadHTMLString() 
    } 

    func loadHTMLString() { 
     let webView = WKWebView(frame: self.view.frame) 
     webView.loadHTMLString("<html><body><p>Hello, World!</p></body></html>", baseURL: nil) 
     self.view.addSubview(webView) 
     createPDFFromView(webView, saveToDocumentWithFileName: "test.pdf") 
    } 

    func createPDFFromView(view: NSView, saveToDocumentWithFileName fileName: String) { 
     let pdfData = view.dataWithPDFInsideRect(view.bounds) 
     if let documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first { 
      let documentsFileName = documentDirectories + "/" + fileName 
      debugPrint(documentsFileName) 
      pdfData.writeToFile(documentsFileName, atomically: false) 
     } 
    } 

} 

E 'piuttosto semplice, quello che sto facendo è la creazione di una WebView e la scrittura di alcuni contenuti HTML di base ad esso che rende questo:

View

e poi prende la vista e lo salva in un file PDF, ma che esce in bianco:

PDF

Ho provato ad afferrare il contenuto da WebView e View ma non è stato piacevole.

Ho trovato un problema simile qui How to take a screenshot when a webview finished rending relativo al salvataggio della visualizzazione Web su un'immagine, ma finora non ho avuto fortuna con una soluzione OSX.

Potrebbe essere qualcosa a che fare con le dimensioni del documento? o che il contenuto è in una sottoview? forse se si cattura la vista non è possibile acquisire la sub immagine?

Qualche idea?

+0

Ciao. Se hai trovato una soluzione al tuo problema, * pubblicalo come risposta *, non aggiungerlo alla tua domanda. Inoltre, per favore non aggiungere "risolto" al titolo. Pubblicare una risposta e contrassegnarla come accettata è il modo di "risolvere" una domanda. Grazie. – Moritz

+0

Scusa, lo farò. –

+0

Nessun problema: ho già ripristinato la modifica, devi solo pubblicare la tua risposta ora. Grazie! :) – Moritz

risposta

1

Quindi ho capito come risolverlo, si scopre che non è possibile (specialmente su OSX) accedere e stampare una visualizzazione Web da un WKWebView.

È necessario utilizzare una WebView e NON una WKWebView (originariamente ho iniziato con WKWebView perché alcuni degli articoli che ho letto dicevano di usarlo).

Un oggetto WebView è più o meno simile a un oggetto WKWebView, che è divertente come l'inferno :-)

Ma consente di accedere a .mainFrame & .frameView di cui avrete bisogno per stampare il suo contenuto.

Ecco il mio codice:

let webView = WebView(frame: self.view.frame) 
    let localfilePath = NSBundle.mainBundle().URLForResource(fileName, withExtension: "html"); 
    let req = NSURLRequest(URL: localfilePath!); 
    webView.mainFrame.loadRequest(req) 
    self.view.addSubview(webView) 

Una volta che è reso Ho poi aggiunto un ritardo di 1 secondo solo per assicurarsi che il contenuto è reso prima di stamparlo,

// needs 1 second delay 
    let delay = 1 * Double(NSEC_PER_SEC) 
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay)) 
    dispatch_after(time, dispatch_get_main_queue()) { 
     // works! 
     let data = webView.dataWithPDFInsideRect(webView.frame) 
     let doc = PDFDocument.init(data: data) 
     doc.writeToFile("/Users/john/Desktop/test.pdf") 

     // works! 
     let printInfo = NSPrintInfo.sharedPrintInfo() 
     let printOperation = NSPrintOperation(view: webView.mainFrame.frameView, printInfo: printInfo) 
     printOperation.runOperation() 
    } 

Qui sto stampa e salvandolo come PDF, solo così sono doppiamente sicuro che funzioni in tutte le circostanze.

Sono sicuro che può essere migliorato, odio il ritocco hack, dovrebbe sostituirlo con una sorta di callback o delega da eseguire quando il contenuto è completamente caricato.