Как запустить команду 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, которое может находиться в состояниях:

  1. состояние: пустое тело
  2. состояние: некоторая загрузка
  3. состояние: фреймворк javascript сделал свое дело и вставил тело приложения внутрь
  4. состояние: тело имеет содержание

"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)
Другие вопросы по тегам