广泛关注此问题,无法解决。
我正在使用1个WKWebViews和一个远程url,其中包含可以发布和接收js消息的html / js代码。
需要了解的2条消息是open
和broadcast
。
假设我的Viewcontroller中有2个按钮,一个按钮名为open
,另一个按钮broadcast
都触发了js回调。当我点击open
时,我将视图控制器推到屏幕上,open
js回调将返回下一个要为WebView加载的请求的URL。
此功能运行良好,每次点击打开按钮时,我按下一个新的视图控制器(与包含open
和broadcast
按钮的视图控制器相同。
现在的问题是,broadcast
按钮的规格是,当点击它时,我必须获取WebView的后备列表,并且对于每个后备列表项,我都必须向该网页发送js消息。
最终结果是应根据broadcast
数据更新WebViews列表中的所有先前页面。
我当前的解决方案(不起作用:()是,对于每个backItem,我创建一个WKWebView并在该新创建的WebView上加载该调用的URL调用validateJavascript方法。
但是每次执行javascript时都会收到此错误-
Optional(Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred"
UserInfo={WKJavaScriptExceptionLineNumber=1,
WKJavaScriptExceptionMessage=ReferenceError: Can't find variable: JSBridge, WKJavaScriptExceptionColumnNumber=10,
WKJavaScriptExceptionSourceURL=about:blank, NSLocalizedDescription=A JavaScript exception occurred})
这是触发该错误的代码
func broadcast<T: Codable>(_ jsElement: JSElement, with data: T) {
let backlists = webview.backForwardList.backList
return recursiveBroadcast(jsElement, backlists: backlists, data: data)
}
private func recursiveBroadcast<T: Codable>(_ jsElement: JSElement, backlists: [WKBackForwardListItem], data: T) {
guard !backlists.isEmpty, let backlist = backlists.last else { return }
var shortenedBacklist = backlists
shortenedBacklist.removeLast()
let request = URLRequest(url: backlist.initialURL)
broadcastWebView.load(request)
let _ = (broadcastWebView.evalJavascript(javascriptFuncName: jsElement.method) as Promise<Any?>).done { a in }
recursiveBroadcast(jsElement, backlists: shortenedBacklist, data: data)
}
我还使用PromiseKit
来包装evaluateJavascript
WKWebViews调用,以防您疑惑:D
正在发送到broadcastWebView的js方法是
JSBridge.receive('{"eventType":"broadcast","data":{"data":{"type":"push","val":"water"}}}')