Skip to content

Instantly share code, notes, and snippets.

@frzi
Created November 19, 2022 18:15
Show Gist options
  • Save frzi/0bf003f74698af7656dfd94cfdec803e to your computer and use it in GitHub Desktop.
Save frzi/0bf003f74698af7656dfd94cfdec803e to your computer and use it in GitHub Desktop.
Simple WebView in SwiftUI
import Combine
import SwiftUI
import WebKit
struct WebView: NSViewRepresentable {
let url: URL
@Binding var title: String
private(set) var onCommitHandlers: [(URL) -> Void] = []
func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeNSView(context: Context) -> WKWebView {
let webview = WKWebView()
webview.navigationDelegate = context.coordinator
context.coordinator.setWebView(webview)
return webview
}
func updateNSView(_ webView: WKWebView, context: Context) {
context.coordinator.onCommitHandlers = onCommitHandlers
context.coordinator.title = $title
if context.coordinator.initialUrl != url {
context.coordinator.initialUrl = url
webView.load(URLRequest(url: url))
}
}
func onCommit(perform handler: @escaping (URL) -> Void) -> Self {
var copy = self
copy.onCommitHandlers.append(handler)
return copy
}
final class Coordinator: NSObject, WKNavigationDelegate {
private weak var webView: WKWebView?
private var cancellables = Set<AnyCancellable>()
fileprivate var onCommitHandlers: [(URL) -> Void] = []
fileprivate var initialUrl: URL?
fileprivate var title: Binding<String>?
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
guard let url = webView.url else {
return
}
for handler in onCommitHandlers {
handler(url)
}
}
func setWebView(_ webView: WKWebView) {
self.webView = webView
webView.publisher(for: \.title)
.compactMap { $0 }
.sink { [weak self] newTitle in
self?.title?.wrappedValue = newTitle
}
.store(in: &cancellables)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment