Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

54
Vistas
using callAsyncJavaScript in WKWebView

What difference between methods callAsyncJavaScript and evaluateJavaScript? Using it with same script like:

evaluateJavaScript("document.documentElement.outerHTML.toString()")

and

callAsyncJavaScript("document.documentElement.outerHTML.toString()")

returns different results: HTML in first, and .sucess(nil) in second...

almost 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

There are 3 methods that allow to run JS from WKWebView (well, there's more signatures, but 3 principle methods):

  • The oldest and most primitive is evaluateJavaScript(_:completionHandler:), which allows to run arbitrary piece of code. This day and age, there's no excuse to use, as it has no benefits over the other methods.

  • The more modern improved version is evaluateJavaScript(_:in:in:completionHandler:) which was introduced in iOS 14. It can be used to run synchronous code. It uses a modern way to present a result - Result<Any, Error>, which allows to encapsulate any sort of result, success or failure in a single convenient to use object. But the key difference is that it allows you to specify the context of the script, which prevents conflicts between different scripts:

Executing a script in its own content world effectively gives it a separate copy of the environment variables to modify.

  • But neither of these functions is able to support asynchronous JavaScript code, i.e. promise. You can implement promise execution if you combine evaluateJavaScript with WKScriptMessage (e.g. as explained here), but it's very awkward. So callAsyncJavaScript(_:arguments:in:in:completionHandler:) solves that problem: you can use it to execute a Promise, without additional help of WKScriptMessage, which makes code less distributed, and easier. Here's an example of how it's done.

It also has 2 additional advantages of this method:

  • The first argument is no longer a function name, but functionBody, which becomes an anonymous function, and prevents the naming conflicts possible due to global scope of the function.
  • And also arguments are separated from the body as [String : Any], which allow us to define function body somewhere statically, and reuse it by passing the arguments (as opposed to injecting them to function body as you need with evaluateJavaScript.

So you should be using this method for executing asynchronous JS code, and you can use it for the synchronous code.

One more thing: with callAsyncJavaScript you need to remember that you are defining the function body, so if you want something returned, you need to use the word return (as opposed to evaluateJavaScript, where you defined a piece of code to run, which can have no return, unless you define a function).

almost 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda