Как запустить команду javascript в WKWebView Swift
Я пытаюсь запустить команду javascript, которая работает, если я запускаю ее в консоли в Интернете. Я пробовал выполнить приведенный ниже код, но в ответ продолжаю получать ноль.
webView.evaluateJavaScript("command") { (result, error) in
if error == nil {
print(result)
} else {
print(error)
}
}
2 ответа
В случае, если ваш веб-просмотр дополнительно загружает часть тела (или всего тела html), вы не получите желаемых результатов, оценивая свой javascript внутри метода:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
Причина этого в том, что метод didFinish вызывается после того, как навигация выполняется внутри webview, но не строго после загрузки всего содержимого внутри webView, которое может находиться в состояниях:
- состояние: пустое тело
- состояние: некоторая загрузка
- состояние: фреймворк javascript сделал свое дело и вставил тело приложения внутрь
- состояние: тело имеет содержание
"didFinish" вызывается в состоянии 1. Вы можете подождать некоторое время с DispatchQueue.main.asyncAfter, а затем выполнить .evaluateJavascript, но он заставит webView вносить изменения перед пользователем (уродливо, на мой взгляд ...)
Мое предложение было бы таким расширением:
extension WKWebView {
// it re-execute javascript in cases when body is attached additionally on the html by some inner javascript framework
// it tries around 50 times maximum in time range of 10 sec
// if body is not loaded in 10 secs, this won't work
func rexecuteJavascript(tryouts: Int = 0, script: String) {
self.evaluateJavaScript(script, completionHandler: { (result: Any?, error: Error?) in
if let _ = error, tryouts < 50 {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
return self.rexecuteJavascript(tryouts: tryouts + 1, script: script)
}
}
})
}
}
Он отлично работает для меня, потому что тело веб-просмотра заполняется примерно через 2-3 секунды после "didFinish", и я использую это для выполнения моего javascript в полностью загруженном теле:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
let removeFooterScript = "document.getElementsByClassName('global-footer')[0].style.display='none';"
webView.rexecuteJavascript(script: removeFooterScript)
}
Ваше здоровье!
Вот код для внедрения кода javascript в ваш WKWebView
let wkUScript = WKUserScript(source: "your javascript command",
injectionTime: .atDocumentEnd,
forMainFrameOnly: true)
let wkUController = WKUserContentController()
wkUController.addUserScript(wkUScript)
let wkWebConfig = WKWebViewConfiguration()
wkWebConfig.userContentController = wkUController
let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: 400, height: 400), configuration: wkWebConfig)