Swift 在后台线程中更新 WKWebView 内容失败
Update WKWebView content by Swift failed in background thread
我想执行以下操作:
- 我在 WKWebView 中点击一个 div 元素并发送消息到 swift。 - 确定
- Swift 通过 http 请求进行处理以接收 json。 - 确定
- Swift 将此 json 发送到 javascript 或 swift 更改 WKWebView DOM - FAILED
我的 javascript 函数发送消息给 Swift:
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 );
}
它给我这个错误:
如何处理 DOM 由 swift 更改?
----- 编辑 -----
我试过了,但错误仍然存在。
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
完成块不在主线程上 运行。只需在主线程上调用 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()
}
我想执行以下操作:
- 我在 WKWebView 中点击一个 div 元素并发送消息到 swift。 - 确定
- Swift 通过 http 请求进行处理以接收 json。 - 确定
- Swift 将此 json 发送到 javascript 或 swift 更改 WKWebView DOM - FAILED
我的 javascript 函数发送消息给 Swift:
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 );
}
它给我这个错误:
如何处理 DOM 由 swift 更改?
----- 编辑 -----
我试过了,但错误仍然存在。
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
完成块不在主线程上 运行。只需在主线程上调用 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()
}