WKWebView 不调用导航委托方法

WKWebView not calling navigation delegate methods

我正在尝试使用答案 here 将 html 文件导出为 pdf,该答案使用 WKWebView 加载 html 字符串,然后绘制从那PDF。我还需要它在 Catalyst 上工作,这就是我使用这种方法的原因。

发生的事情是 WKWebView 从未调用它的 navigationDelegate 方法。我在一堆委托方法中放了一堆 print() 语句,但我得到的唯一输出是:

::::: SET WEBVIEW
Loaded

我不知道是什么让 WKWebView 不调用它的委托方法。我也试过加载 URL 之类的 https://google.com 并且它以同样的方式失败。我什至从 webview 观察到加载进度,它正在加载内容,只是没有调用委托。

非常感谢任何帮助,我需要它来工作。

class ReportsRenderer: NSObject {

    var webView: WKWebView? = nil {
        didSet {
            print("::::: SET WEBVIEW")
        }
    }
    var completion: PDFCompletion!
    typealias PDFCompletion = (Result<NSData, Error>) -> Void
    
    func exportPDF(html: String, completion: @escaping PDFCompletion) throws {
        
        self.completion = completion
        
        webView = WKWebView()
        webView?.navigationDelegate = self
        
        let baseURL = URL(fileURLWithPath: NSTemporaryDirectory())
        webView?.loadHTMLString(html, baseURL: baseURL)
        print("Loaded")

    }
    
    
    func createPDF(_ formatter: UIViewPrintFormatter) {
        print("Creating PDF")
        let printPageRenderer = UIPrintPageRenderer()
        printPageRenderer.addPrintFormatter(formatter, startingAtPageAt: 0)
        
        let paperRect = CGRect(x: 0, y: 0, width: 595.2, height: 841.8)
        let padding: CGFloat = 20
        let printableRect = paperRect.insetBy(dx: padding, dy: padding)
        printPageRenderer.setValue(printableRect, forKey: "printableRect")
        printPageRenderer.setValue(paperRect, forKey: "paperRect")

        printPageRenderer.footerHeight = 70
        printPageRenderer.headerHeight = 20
        
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
        for i in 0..<printPageRenderer.numberOfPages {
            UIGraphicsBeginPDFPage();
            printPageRenderer.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
        }
        UIGraphicsEndPDFContext();
        
        self.completion?(.success(pdfData))
    }
}

extension ReportsRenderer: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("::::: WEBVIEW NAVIGATED")
        let viewPrintFormatter = webView.viewPrintFormatter()
        createPDF(viewPrintFormatter)
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print("::::: WEBVIEW ERROR")
        print(error.localizedDescription)
    }
    
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        print("::::: WEBVIEW DIDCOMMIT NAVIGATION")
    }
    
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("::::: WEBVIEW didStartProvisionalNavigation")
    }
}

我在 ViewController 中这样称呼它:

do {
            try ReportsRenderer().exportPDF(html: string) { (result) in
                switch result {
                case .success(let pdfData):
                    // ---- This is never called -----
                    print("Made the pdf data!")
                    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
                    let pdfFilename = paths[0].appendingPathComponent("\(UUID().uuidString).pdf")
                    pdfData.write(to: pdfFilename, atomically: true)

                case .failure(let error):
                    // ---- This is also never called -----
                    print("::::: Error")
                    print(error.localizedDescription)
                }
            }
        } catch {
            // There isn't an error here either
            print("::::: Error")
            print(error)
        }

您需要在 ViewController 中创建 ReportsRenderer 的实例才能使其正常工作。当您在 ViewController 中创建一个实例时,它的寿命与 ViewController 的寿命一样长。在您的情况下,它会立即取消初始化。

class ViewController: UIViewController {
    let reportsRenderer = ReportsRenderer()
    // then...
    do {
        try reportsRenderer.exportPDF(html: string) { (result) in
    //...
}