The code has been tested on July 7, 2021 on macOS 11.4.
Based on https://gist.github.com/swiftui-lab/a873bf413770db6fd1a525fa424ce8cd by swiftui-lab.
Usage: https://florianschulz.info/portfolio/writing/wrapping-websites-in-webviews-using-swiftui
The code has been tested on July 7, 2021 on macOS 11.4.
Based on https://gist.github.com/swiftui-lab/a873bf413770db6fd1a525fa424ce8cd by swiftui-lab.
Usage: https://florianschulz.info/portfolio/writing/wrapping-websites-in-webviews-using-swiftui
import SwiftUI | |
@available(OSX 11.0, *) | |
struct ContentView: View { | |
private var url: URL? = URL(string: "https://apple.com") | |
init() { | |
print("Hello World") | |
} | |
var body: some View { | |
WebView(data: WebViewData(url: self.url!)) | |
} | |
} | |
import SwiftUI | |
import WebKit | |
import Combine | |
class WebViewData: ObservableObject { | |
@Published var loading: Bool = false | |
@Published var url: URL?; | |
init (url: URL) { | |
self.url = url | |
} | |
} | |
@available(OSX 11.0, *) | |
struct WebView: NSViewRepresentable { | |
@ObservedObject var data: WebViewData | |
func makeNSView(context: Context) -> WKWebView { | |
return context.coordinator.webView | |
} | |
func updateNSView(_ nsView: WKWebView, context: Context) { | |
guard context.coordinator.loadedUrl != data.url else { return } | |
context.coordinator.loadedUrl = data.url | |
if let url = data.url { | |
DispatchQueue.main.async { | |
let request = URLRequest(url: url) | |
nsView.load(request) | |
} | |
} | |
context.coordinator.data.url = data.url | |
} | |
func makeCoordinator() -> WebViewCoordinator { | |
return WebViewCoordinator(data: data) | |
} | |
} | |
@available(OSX 11.0, *) | |
class WebViewCoordinator: NSObject, WKNavigationDelegate { | |
@ObservedObject var data: WebViewData | |
var webView: WKWebView = WKWebView() | |
var loadedUrl: URL? = nil | |
init(data: WebViewData) { | |
self.data = data | |
super.init() | |
webView.navigationDelegate = self | |
} | |
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { | |
DispatchQueue.main.async { | |
self.data.loading = false | |
} | |
} | |
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { | |
DispatchQueue.main.async { self.data.loading = true } | |
} | |
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { | |
showError(title: "Navigation Error", message: error.localizedDescription) | |
DispatchQueue.main.async { self.data.loading = false } | |
} | |
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { | |
showError(title: "Loading Error", message: error.localizedDescription) | |
DispatchQueue.main.async { self.data.loading = false } | |
} | |
func showError(title: String, message: String) { | |
#if os(macOS) | |
let alert: NSAlert = NSAlert() | |
alert.messageText = title | |
alert.informativeText = message | |
alert.alertStyle = .warning | |
alert.runModal() | |
#else | |
print("\(title): \(message)") | |
#endif | |
} | |
} |
Nevermind I was able to of a a javascript workaround! Thanks for the tutorial regardless :) I have to point out one thing though: idk if it's how we setup webview in your tutorial or just the nature of WKWebView in general, but regular keyboard shortcuts like 'cmd+A' to select text don't work inside the webview. I'm looking into that right now but if you have any info, let me know. You can easily reproduce the error on your side by just running something in webview and trying to select text inside of that.