Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

705
Visualizações
WKWebView: evalúa JavaScript sin ver cambios

En mi aplicación SwiftUI, usé WKWebView para actualizar algunas etiquetas html desde el lado nativo, usando SwiftUI TextFields. Para que la comunicación funcione, estoy usando el método de evaluación de JavaScript evaluateJavaScript() para enviar datos de nativo a webview.

Mi código se ve así:

 struct DemoView: View { @State private var headline: String = "Initial" var body: some View { NavigationView { VStack { Form { TextField("Your headline", text: $headline) } WebView(headline: $headline) } } } } import WebKit let bridgeHTML = """ <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, minimum-scale=1, viewport-fit=cover"> </head> <body> <h3 id="headline">Headline</h3> <script> // to receive messages from native webkit.messageHandlers.bridge.onMessage = (msg) => { document.getElementById("headline").textContent = msg } </script> </body> </html> """ struct WebView: UIViewRepresentable { @Binding var headline: String class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { } private var owner: WebView init(owner: WebView) { self.owner = owner } var webView: WKWebView? func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { self.webView = webView self.messageToWebview(msg: self.owner.headline) // initial value loading !! } func messageToWebview(msg: String) { self.webView?.evaluateJavaScript("webkit.messageHandlers.bridge.onMessage('\(msg)')") } } func makeCoordinator() -> Coordinator { return Coordinator(owner: self) } func makeUIView(context: Context) -> WKWebView { let userContentController = WKUserContentController() userContentController.add(context.coordinator, name: "bridge") let configuration = WKWebViewConfiguration() configuration.userContentController = userContentController let _wkwebview = WKWebView(frame: .zero, configuration: configuration) _wkwebview.navigationDelegate = context.coordinator guard let path: String = Bundle.main.path(forResource: "index", ofType: "html") else { return _wkwebview } let localHTMLUrl = URL(fileURLWithPath: path, isDirectory: false) _wkwebview.loadFileURL(localHTMLUrl, allowingReadAccessTo: localHTMLUrl) // _wkwebview.loadHTMLString(bridgeHTML, baseURL: nil) // << used for testing return _wkwebview } func updateUIView(_ webView: WKWebView, context: Context) { // this works for update, but for initial it is too early !! webView.evaluateJavaScript("webkit.messageHandlers.bridge.onMessage('\(headline)')") } }

Funciona, dentro del método de delegado didFinish() configuro los valores iniciales para representar en la página web. Y cuando escribo algo, se actualiza automáticamente en la página web. hasta ahora todo bien, pero si no hago nada durante más tiempo (alrededor de 1 minuto) o si cambio la aplicación (no la cierro) y vuelvo a la aplicación y luego cambio algo en el campo de texto, la página web es ya no se actualiza automáticamente.

Por supuesto, podría ejecutar webView.reload() , pero luego pierdo mi estado anterior. En lugar de Initial , obtengo Titular. Lógico porque esto se configuró dentro de la etiqueta h3, pero eso es lo que quiero evitar.

Entonces, ¿cómo puedo asegurarme de que siempre que se evaluteJavascript() , la página web también se actualice sin perder el estado anterior, sin importar cuánto tiempo espere o si cambio de aplicación? ¿Hay alguna forma de resolver esto?

ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Esto parece un defecto de Apple, porque se llama a updateUIView, pero evaluateJavaScript (JavaScript interno) genera una excepción, porque se pierde bridge.onMessage y no una función más.

Aquí se encuentra una solución alternativa: restablecer WebView en la activación de la escena (la aplicación pasa a primer plano), ya que se recreó con los estados actuales, se conservan los valores anteriores. Probado con Xcode 13.2 / iOS 15.2

 struct DemoView: View { @Environment(\.scenePhase) var scenePhase @State private var headline: String = "Initial" @State private var reset = false var body: some View { NavigationView { VStack { Form { TextField("Your headline", text: $headline) } WebView(headline: $headline).id(reset) // << here !! .onChange(of: scenePhase) { if case .active = $0 { self.reset.toggle() // << here !! } } } } } }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda