WKWebView未调用导航委托方法 [英] WKWebView not calling navigation delegate methods

查看:0
本文介绍了WKWebView未调用导航委托方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

::::: SET WEBVIEW
Loaded

我搞不懂是什么原因使WKWebView不调用它的委托方法。我也尝试过加载类似https://google.com的URL,但同样失败了。我甚至观察到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")
    }
}

我在我的视图控制器中调用它,如下所示:

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
    //...
}

这篇关于WKWebView未调用导航委托方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆