2016-10-25 15 views
5

Im stworzenie pliku PDF z zawartością html w szybkim 3,0:UIMarkupTextPrintFormatter nigdy base64 renderuje obrazy

/** 
* 
*/ 
func exportHtmlContentToPDF(HTMLContent: String, filePath: String) { 
    // let webView = UIWebView(frame: CGRect(x: 0, y: 0, width: 694, height: 603)); 

    // webView.loadHTMLString(HTMLContent, baseURL: nil); 

    let pdfPrinter = PDFPrinter(); 
    let printFormatter = UIMarkupTextPrintFormatter(markupText: HTMLContent); 
    // let printFormatter = webView.viewPrintFormatter(); 

    pdfPrinter.addPrintFormatter(printFormatter, startingAtPageAt: 0); 

    let pdfData = self.drawPDFUsingPrintPageRenderer(printPageRenderer: pdfPrinter); 

    pdfData?.write(toFile: filePath, atomically: true); 
} 

/** 
* 
*/ 
func drawPDFUsingPrintPageRenderer(printPageRenderer: UIPrintPageRenderer) -> NSData! { 
    let data = NSMutableData(); 

    UIGraphicsBeginPDFContextToData(data, CGRect.zero, nil); 

    printPageRenderer.prepare(forDrawingPages: NSMakeRange(0, printPageRenderer.numberOfPages)); 

    let bounds = UIGraphicsGetPDFContextBounds(); 

    for i in 0...(printPageRenderer.numberOfPages - 1) { 
     UIGraphicsBeginPDFPage(); 

     printPageRenderer.drawPage(at: i, in: bounds); 
    } 

    UIGraphicsEndPDFContext(); 

    return data; 
} 

Wszystko jest renderowany w porządku z wyjątkiem moich base64 zakodowane obrazy. Zawartość HTML w przeglądarce internetowej lub przeglądarce Safari lub Chrome jest poprawnie wyświetlana i poprawnie wyświetla wszystkie obrazy. Ale obrazy nigdy nie są wyświetlane w pliku PDF.

Dlaczego obrazy nie są renderowane i jak mogę je renderować?

+0

Polecam zrobić eksperyment. Kreta HTML zawierająca dwa obrazy. Pięść jest zakodowana w base64, a druga wskazuje na plik obrazu. Otwórz ten obraz za pomocą przeglądarki Safari na iPhonie. Następnie wyeksportuj go do iBooks jako plik PDF. Zobacz też, czy oba obrazy są renderowane przez natywną aplikację Safari. – Ramis

+0

Czy robisz to na platformę iOS? – Ramis

+0

Robię to na platformę iOS tak. Przetestuję to z plikiem obrazu, ale przy okazji. kiedy otwieram przeglądarkę internetową zawierającą mój szablon html, obrazy base64 są wyświetlane poprawnie. – Mulgard

Odpowiedz

3

Dzieje się tak, ponieważ pierwszy WebKit analizuje HTML do DOM i czyni zawartość na wiele cykli pętli zdarzenia. Dlatego należy poczekać nie tylko na to, aby strona DOM była gotowa, ale aby ładowanie zasobów było kompletne. Jak również sugerujesz, musisz tak skonstruować kod, aby widok internetowy był ładowany jako pierwszy, a następnie eksportować jego zawartość.

Aby ustalić właściwy czas na ogień eksport, można obserwować za stan dokumentu DOM w widoku internetowej. Istnieje wiele sposobów, aby to zrobić, ale opcja najbardziej czytelny znajdę to a port of an answer to a related Objective-C question: w implementacji UIWebViewDelegate, wdrożyć webViewDidFinishLoad w następujący sposób monitorować document.readyState:

func webViewDidFinishLoad(_ webView: UIWebView) { 

     guard let readyState = webView.stringByEvaluatingJavaScript(from: "document.readyState"), 
      readyState == "complete" else 
     { 
      // document not yet parsed, or resources not yet loaded. 
      return 
     } 

     // This is the last webViewDidFinishLoad call --> export. 
     // 
     // There is a problem with this method if you have JS code loading more content: 
     // in that case -webViewDidFinishLoad can get called again still after document.readyState has already been in state 'complete' once or more. 
     self.exportHtmlContentToPDF(…) 
    } 
+0

Dla mnie to nieustannie migocze mój ekran bez końca – RJH

+1

Dlaczego bierzesz o WebKit, jeśli pytanie dotyczy UIMarkupTextPrintFormatter? –

1

Znalazłem rozwiązanie!

Eksport do pliku PDF następuje przed zakończeniem renderowania. Jeśli umieścisz bardzo małe zdjęcie, pojawi się ono w pliku PDF. Jeśli obraz jest zbyt duży, renderowanie trwa zbyt długo, ale eksport PDF nie czeka na zakończenie renderowania.

Więc co zrobiłem, aby praca jest następujący:

Przed wyeksportować do pliku PDF pokażę wynikiem HTML w WebView. WebView renderuje wszystko poprawnie i teraz, gdy naciskam na eksport do pliku PDF, plik PDF wyświetla się poprawnie ze wszystkimi obrazami w środku.

Sądzę więc, że jest to duże opóźnienie, którego nie można powiedzieć, że eksporter plików PDF ma czekać na zakończenie procesu renderowania.

+1

Tak, parsowanie i ładowanie DOM jest asynchroniczne. Na szczęście jest prosty sposób na określenie dokładnego czasu, w którym dokument jest gotowy do eksportu, co opisałem w mojej odpowiedzi: http://stackoverflow.com/a/40320983/504931 – mz2