繁体   English   中英

Window webkit 失败 postMessage iOS Swift

[英]Window webkit failure postMessage iOS Swift

我正在尝试创建一个库,它在 class 中打开一个 web 视图,目标已打开但在屏幕上看不到它。 我创建并尝试执行生成 postMessage 的 javaScript,以在方法 userContentController() 中获取结果,例如,但我在执行它时遇到错误。 另外,我使用了 webView.callAsyncJavaScript,因为我想执行一些 webView.evaluateJavaScript 不允许的异步函数。 有些人知道可能是什么原因可以帮助我。 谢谢。

代码:

import WebKit

class FingerprintJs : NSObject, WKScriptMessageHandler, WKNavigationDelegate{
    
    public func tryFinger(){
        getWebView()
    }
    
    public func userContentController(_ userContentController: WKUserContentController,
                                      didReceive message: WKScriptMessage){
        print("userContentController")
        print(message.name)
    }
    
    private func getWebView(){
        if let viewController = UIWindow.key?.rootViewController {
            if Thread.isMainThread {
                let webView = self.makeWebView(viewController: viewController as! ViewController)
                webView.loadHTMLString(getHtml(), baseURL: nil)
                if #available(iOS 14.0, *) {
                    print("bunea")
                    webView.callAsyncJavaScript(getJavaScript()!, arguments: [:], in: nil, in: .defaultClient, completionHandler:{(result) in
                        print("queeeeee")
                        print(result as Any)
                    })
                } else {
                    print("Llegaste aca? porqueee ")
                    // Fallback on earlier versions
                }
//                webView.evaluateJavaScript(getJavaScript()!,completionHandler:{(result , error) in
//                    if error == nil {
//                        print("success")
//                        print(result as Any)
//                    }
//                    else {
//                        print("error in executing js ", error!)
//                    }
//                })
            } else {
               print("Llegaste aca? ")
            }

            
        }else{
            NSLog("The UIApplication keyWindow of the rootViewController must be loaded first", "")
        }
    }
        
    private func makeWebView(viewController: ViewController) -> WKWebView {
        let preferences = WKPreferences()
        preferences.javaScriptEnabled = true
        let config = WKWebViewConfiguration()
        config.userContentController.add(self, name: "message5")
        config.preferences = preferences
        let webView = WKWebView(frame: .init(x: 1.0, y: 1.0, width: 0, height: 0),
                                configuration: config)
        webView.translatesAutoresizingMaskIntoConstraints = false
        viewController.view.addSubview(webView)
        return webView
    }
    
    private func getJavaScript() -> String?{
        var javaScript: String? = nil
        if let jsSourcePath = Bundle.main.path(forResource: "ejemplo", ofType: "js") {
            do {
                javaScript = try String(contentsOfFile: jsSourcePath)
            }
            catch {
                NSLog("getJavaScriptString: "+(error.localizedDescription), "")
            }
        }
        return javaScript
    }
    
    private func getHtml() -> String {
        let html: String =
            """
            <html>
                <body>
                    <script>
                    </script>
                </body>
            </html>
            """
        return html
    }
    
    private var webView: WKWebView? {
        didSet {
            oldValue?.removeFromSuperview()
            oldValue?.configuration.userContentController.removeScriptMessageHandler(forName: "message5")
        }
    }
    
   
}

extension UIWindow {
    static var key: UIWindow? {
        if #available(iOS 13, *) {
            return UIApplication.shared.windows.first { $0.isKeyWindow }
        } else {
            return UIApplication.shared.keyWindow
        }
    }
}

Javascript :

testFunct();
function testFunct() {
    window.webkit.messageHandlers.message5.postMessage("nice" )
}

错误

failure(Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred" UserInfo={WKJavaScriptExceptionLineNumber=0, WKJavaScriptExceptionMessage=TypeError: undefined is not an object (evaluating 'window.webkit.messageHandlers'), WKJavaScriptExceptionColumnNumber=0, NSLocalizedDescription=A JavaScript exception occurred})

此外,例如这里我对代码进行了一些更改,但例如我从未在方法 userContentController 中收到消息。 我在 html 中设置 window.webkit.messageHandlers 的地方。

import WebKit
import UIKit

class FingerprintJs : NSObject, WKScriptMessageHandler, WKNavigationDelegate{
    
    public func tryFinger(){
        getWebView()
    }
    
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        assert(message.name == "myMessageName")
    }
    
    private func getWebView(){
        if let viewController = UIWindow.key?.rootViewController {
            if Thread.isMainThread {
                let webView = self.makeWebView(viewController: viewController as! ViewController)
                webView.loadHTMLString(getHtml(), baseURL: nil)
//                webView.evaluateJavaScript(getJavaScript()!,completionHandler:{(result , error) in
//                    if error == nil {
//                        print("success")
//                        print(result as Any)
//                    }
//                    else {
//                        print("error in executing js ", error!)
//                    }
//                })
            } else {
               print("Llegaste aca? ")
            }

            
        }else{
            NSLog("The UIApplication keyWindow of the rootViewController must be loaded first", "")
        }
    }
        
    private func makeWebView(viewController: ViewController) -> WKWebView {
        let preferences = WKPreferences()
        preferences.javaScriptEnabled = true
        let config = WKWebViewConfiguration()
        config.userContentController.add(self, name: "myMessageName")
        config.preferences = preferences
        let webView = WKWebView(frame: .init(x: 1.0, y: 1.0, width: 0, height: 0),
                                configuration: config)
        webView.translatesAutoresizingMaskIntoConstraints = false
        viewController.view.addSubview(webView)
        webView.navigationDelegate = self
        return webView
    }
    
    private func getJavaScript() -> String?{
        var javaScript: String? = nil
        if let jsSourcePath = Bundle.main.path(forResource: "ejemplo", ofType: "js") {
            do {
                javaScript = try String(contentsOfFile: jsSourcePath)
            }
            catch {
                NSLog("getJavaScriptString: "+(error.localizedDescription), "")
            }
        }
        return javaScript
    }
    
    private func getHtml() -> String {
        let html: String =
            """
            <html>
                <body>
                    <script>
                        window.webkit.messageHandlers.myMessageName.postMessage("message")
                    </script>
                </body>
            </html>
            """
        return html
    }
    
    private var webView: WKWebView? {
        didSet {
            oldValue?.removeFromSuperview()
            oldValue?.configuration.userContentController.removeScriptMessageHandler(forName: "message5")
        }
    }
    
   
}

extension UIWindow {
    static var key: UIWindow? {
        if #available(iOS 13, *) {
            return UIApplication.shared.windows.first { $0.isKeyWindow }
        } else {
            return UIApplication.shared.keyWindow
        }
    }
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("testFunct()")
}

加载 webView 后,尝试从 didFinish 导航方法调用 JS 方法。 可能是在 webView 正确加载之前调用了 JS 方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM