evaluateJavaScript 等待 JS 回调

Wait for JS Callback After evaluateJavaScript

我正在尝试等待 javascript 回调,但是 swift 回调在 javascript 回调之前被调用。如何等待JS回调?

AppWebView.evaluateJavaScript("$('.loading-gif').removeClass('hide', function() { return true } );") { (Any, Error) in
\ .loading-gif successfully hided.
}

你可以使用这个库https://github.com/marcuswestin/WebViewJavascriptBridge

在 JS 方面:

bridge.registerHandler("show_loading", function(data, responseCallback) {
    $('.loading-gif').removeClass('hide', function() { 
     responseCallback(true) 
    } );
})

Swift 一侧:

self.bridge.callHandler("show_loading",data:nil, handler: { (data:AnyObject!) in
            //do whatever you want...
        })

您可以通过 javascript 回调中的回调通知本机 iOS 代码。如果您将这样的内容添加到您的 javascript:

window.webkit.messageHandlers.observe.postMessage(JSON.stringify( { callback: 'show_loading' } ));

然后在本机端为您的 WKWebView(安装在 WKWebViewConfiguration 上)设置一个 WKUserContentController。您的 userContentController.didReceiveScriptMessage 处理程序将通过从 Javascript 端发送的 JSON 被调用。

无法使用 evaluateJavaScript 执行此操作,因为一旦评估 Javascript returns 就会调用它的回调。这很可能发生在您的异步调用完成之前。

您需要在您的 swift 代码中注册一个消息处理程序,类似于...

let script = WKUserScript(source: javascriptString, 
                          injectionTime: injectionTime, 
                          forMainFrameOnly: true)
userContentController.addUserScript(script)
webView.configuration.userContentController.addScriptMessageHandler(self, 
                                            name: "didShowLoading")

然后您可以在 Swift 代码中定义委托方法…

func userContentController(userContentController: WKUserContentController,
    didReceiveScriptMessage message: WKScriptMessage) {

    if message.name == "didShowLoading" {
        // do something
    }
}

最后,您可以 post 来自 javascript 代码的消息…

var script = "$('.loading-gif').removeClass('hide', function() {"
           + "  webkit.messageHandlers['didShowLoading'].postMessage('');"
           + "});"
webView.evaluateJavaScript(script)