Cómo mostrar un WebView en SwiftUI

1. Crear un ObservableObject

Primero se crea un ObservableObject para que se pueda comunicar con el UIViewRepresentable que se va a crear más adelante.

class WebViewModel: ObservableObject {
@Published var isLoading: Bool = false
@Published var canGoBack: Bool = false
@Published var shouldGoBack: Bool = false
@Published var title: String = ""
var url: String
init(url: String) {
self.url = url
}
}
  • isLoading: Conocer si el WebView ha terminado de cargar, así si queremos podemos crear un Loader o Spinner y mejorar la experiencia del usuario notificándole cuando ha terminado de cargar el WebView.
  • canGoBack: Conocer si se ha navegado a una página nueva y poder navegar hacia atrás.
  • shouldGoBack: Permitir o no navegar hacia atrás.
  • title: Título del WebView.
  • url: Ruta a abrir por el WebView.

Cómo vemos, éste ViewModel nos va a permitir tener un control sobre lo que está pasando con el WebView tanto en el UIViewRepresentable que vamos a explicar a continuación, como en la vista donde añadiremos el WebView.

2. Crear un UIViewRepresentable con el WebView

import SwiftUI
import WebKit
struct WebViewContainer: UIViewRepresentable {
@ObservedObject var webViewModel: WebViewModel
func makeCoordinator() -> WebViewContainer.Coordinator {
Coordinator(self, webViewModel)
}
func makeUIView(context: Context) -> WKWebView {
guard let url = URL(string: self.webViewModel.url) else {
return WKWebView()
}
let request = URLRequest(url: url)
let webView = WKWebView()
webView.navigationDelegate = context.coordinator
webView.load(request)
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
if webViewModel.shouldGoBack {
uiView.goBack()
webViewModel.shouldGoBack = false
}
}
}
  • func makeCoordinator(): Se inicializa el Coordinator, el cual va a responder al WKNavigationDelegate, para poder hacer uso de los métodos de dicho delegado.
  • func makeUIView(context: Context): Se crea el WKWebView y se carga el URLRequest
  • func updateUIView(\_ uiView: WKWebView, context: Context): En caso de que cambie el estado de la aplicación y afecte a ésta vista de UIKit, se llamará a éste método para poder actualizar la vista. Un ejemplo es cuando la variable goBack de nuestro ViewModel cambia a True, el estado se actualiza y ésta función es llamada para poder llamar luego a uiView.goBack().

Ahora se crea una extensión con el Coordinator, que implementará el WKNavigationDelegate con todos los métodos que se necesitan

extension WebViewContainer {
class Coordinator: NSObject, WKNavigationDelegate {
@ObservedObject private var webViewModel: WebViewModel
private let parent: WebViewContainer
init(_ parent: WebViewContainer, _ webViewModel: WebViewModel) {
self.parent = parent
self.webViewModel = webViewModel
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
webViewModel.isLoading = true
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webViewModel.isLoading = false
webViewModel.title = webView.title ?? ""
webViewModel.canGoBack = webView.canGoBack
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
webViewModel.isLoading = false
}
}
}

3. Usar el WebView

Una vez creado el UIViewRepresentable ya se puede usar en cualquier vista de SwiftUI que necesites.

import SwiftUI
struct ContentView: View {
@StateObject var webViewModel = WebViewModel(url: "https://asynclearn.com/")
var body: some View {
WebViewContainer(webViewModel: webViewModel)
.ignoresSafeArea()
}
}
Ejemplo de un WebView en SwiftUI

En conclusión, para poder abrir un WebView con SwiftUI tenemos que hacer uso de un UIViewRepresentable e implementar los métodos del WKNavigationDelegate en el Coordinator. Puedes hacer uso de los métodos que necesites del WKNavigationDelegate.

Comparte este artículo

Subscríbete a nuestro Newsletter

Mantente al día en el mundo de las aplicaciones móviles con nuestro blog especializado.

Artículos semanales

Todas las semanas artículos nuevos sobre el mundo de las aplicaciones móviles.

No spam

No te enviaremos spam, solo contenido de calidad. Puedes darte de baja cuando quieras.

Contenido de calidad

Nada de contenido generado de manera automática usando ChatGPT.

Recomendaciones

Tips indispensables sobre mejores prácticas y metodologías.

© 2024 AsyncLearn