Искал этот вопрос повсюду и не мог понять.
Я работаю с 1 WKWebViews и удаленным URL, который содержит html / js-код, который может публиковать и получать js-сообщения.
2 сообщения, о которых важно знать: open
и broadcast
.
Скажем, у меня в Viewcontroller две кнопки, одна из которых называется open
, а другая broadcast
обе кнопки вызывают обратный вызов js. когда я нажимаю open
, я выдвигаю контроллер представления на экран, и обратный вызов open
js возвращает URL следующего запроса для загрузки для WebView.
Эта функция работает нормально, каждый раз, когда нажимается кнопка открытия, я нажимаю новый контроллер представления (тот же контроллер представления, который содержит кнопки open
& broadcast
.
Теперь проблема в том, что технические характеристики кнопки broadcast
состоят в том, что при ее нажатии я должен получить список веб-просмотра, а для каждого элемента списка - отправлять сообщение js на веб-страницу.
Конечный результат - все предыдущие страницы в бэк-листе WebViews должны обновляться в соответствии с данными broadcast
.
Мое текущее решение (не работает :() заключается в том, что для каждого backItem я создаю WKWebView и загружаю URL-адрес вызова методаvaluJavascript для этих вновь созданных WebView.
Но я получаю эту ошибку каждый раз, когда выполняется 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
Метод js, который отправляется в broadcastWebView, является
JSBridge.receive('{"eventType":"broadcast","data":{"data":{"type":"push","val":"water"}}}')