javascript - 在后台线程中通过 Swift 更新 WKWebView 内容失败

标签 javascript ios swift multithreading wkwebview

我想做以下事情:

  • 我在 WKWebView 中单击一个 div 元素并向 swift 发送消息。 - 好的
  • Swift 通过 http 请求进行处理以接收 json。 - 好的
  • Swift 将此 json 发送到 javascript 或 swift 更改 WKWebView DOM - 失败

我的用于向 Swift 发送消息的 javascript 函数:

function clicar( id, categ ) {
    window.webkit.messageHandlers.jsHandler.postMessage( "{ 'id' : "+id+", 'categ' : '" + categ + "' }" );
}

我的 Swift 接收消息并处理 http 请求:

extension FirstViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "jsHandler" {
             if let messageBody = message.body as? [String: Any], let id = messageBody["id"] as? Int {
                 self.getData( id )
             }
        }
}

func getData( id: Int ) {
    let url = URL( string: "http://192.168.1.11/inter/app/api/varModel/event.php?categ=" + String(id) )


    _ = URLSession.shared.dataTask(with: url!) { (data, req, error) in
        if req != nil {  }

        if let data = data {
            do {
                let json = try JSONSerialization.jsonObject(with: data, options: []) as! [[String: Any]]

                var textJson = json...
                print( text )
                // until here OK

                // FAILED HERE
                self.wk.evaluateJavaScript("mountCateg( '\(textJson)' );", completionHandler: nil)
                } catch {
                print( erro as Any )
            }
        }
    }.resume()
}  

Javascript 操作 DOM:

function mountCateg( data ) {
    let text = "";
    for ( let i = 0; i < data.length; i++ ) {
        text += "<div class='itemCateg' i='"+data[i].id+"' o='"+data[i].idOrganizer+"'>";
        text +=     "<img class='imgEvento' src='http://192.168.1.11/inter/site/imgEvents/"+data[i].imagem+"'>";
        text +=     "<p class='diaEvento'>"+data[i].dataHora+"</p>";
        text +=     "<p class='nomeEvento'>"+data[i].nome+"</p>";
        text +=     "<p class='localEvento'>"+data[i].cidade+"/"+data[i].uf+"</p>";
        text += "</div>";
    }

    $('#listaEventos').html( text );
}

它给我这个错误:

enter image description here

如何通过 swift 处理 DOM 变化?

----- 编辑 -----

我试过了,但错误仍然存​​在。

DispatchQueue.main.async {
    self.wk.evaluateJavaScript("mountCateg( '\(textJson)' );", completionHandler: nil)
}

我也试过:

extension FirstViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "jsHandler" {
             if let messageBody = message.body as? [String: Any], let id = messageBody["id"] as? Int {
                 self.getData( id )
                 DispatchQueue.main.async {
                     self.wk.evaluateJavaScript("mountCateg( '\(textJson)' );", completionHandler: nil)
             }
        }
}

没有错误,但也没有任何反应!没用

最佳答案

URLSession.shared.dataTask 完成 block 不在主线程上运行。只需在主线程上调用 evaluateJavaScript 即可修复它:

func getData( id: Int ) {
    let url = URL( string: "http://192.168.1.11/inter/app/api/varModel/event.php?categ=" + String(id) )

    _ = URLSession.shared.dataTask(with: url!) { (data, req, error) in
        if req != nil {  }

        if let data = data {
            do {
                let json = try JSONSerialization.jsonObject(with: data, options: []) as! [[String: Any]]

                var textJson = json...
                print( text )

                DispatchQueue.main.async { // call evaluateJavascript on the main thread
                    self.wk.evaluateJavaScript("mountCateg( '\(textJson)' );", completionHandler: nil)
                }
            } catch {
                print( erro as Any )
            }
        }
    }.resume()
}

关于javascript - 在后台线程中通过 Swift 更新 WKWebView 内容失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55033652/

相关文章:

javascript - Shadow DOM 中的 React 组件时单击事件不会触发

ios - Hello world 命令行 LLDB iOS 无法解析 'main' 中的断点

ios - CoreData - insertNewObjectForEntityForName 无法设置属性

SwiftDate 和日期计算

javascript - 如何延迟加载 Facebook 的 Like Box?

javascript - 需要在子图选择上显示 X 轴标签

ios - 我可以解决 UIWebView 中的 iOS 8 Voiceover 错误吗?

ios - 变换标签字体大小

ios - 如何将 UITabBarController 与 NavigationBar 和 ScrollView 一起使用?

javascript - 如何在 JavaScript 中中止调用?