112 行
3.0 KiB
Swift
112 行
3.0 KiB
Swift
|
|
import SwiftUI
|
||
|
|
|
||
|
|
#if canImport(UIKit)
|
||
|
|
import WebKit
|
||
|
|
|
||
|
|
@MainActor
|
||
|
|
public struct XWebViewView: UIViewRepresentable {
|
||
|
|
private let config: XWebViewConfig
|
||
|
|
|
||
|
|
public init(config: XWebViewConfig? = nil) {
|
||
|
|
self.config = config ?? XWebViewBridge.shared.currentConfig()
|
||
|
|
}
|
||
|
|
|
||
|
|
public func makeCoordinator() -> Coordinator {
|
||
|
|
Coordinator()
|
||
|
|
}
|
||
|
|
|
||
|
|
public func makeUIView(context: Context) -> WKWebView {
|
||
|
|
let webView = WKWebView(frame: .zero)
|
||
|
|
webView.navigationDelegate = context.coordinator
|
||
|
|
webView.uiDelegate = context.coordinator
|
||
|
|
if let userAgent = config.userAgent {
|
||
|
|
webView.customUserAgent = userAgent
|
||
|
|
}
|
||
|
|
context.coordinator.attach(webView)
|
||
|
|
XWebViewBridge.shared.setController(context.coordinator)
|
||
|
|
if !config.url.isEmpty, let url = URL(string: config.url) {
|
||
|
|
webView.load(URLRequest(url: url))
|
||
|
|
}
|
||
|
|
return webView
|
||
|
|
}
|
||
|
|
|
||
|
|
public func updateUIView(_ webView: WKWebView, context: Context) {
|
||
|
|
context.coordinator.attach(webView)
|
||
|
|
if webView.url == nil, !config.url.isEmpty, let url = URL(string: config.url) {
|
||
|
|
webView.load(URLRequest(url: url))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static func dismantleUIView(_ uiView: WKWebView, coordinator: Coordinator) {
|
||
|
|
coordinator.detach()
|
||
|
|
if XWebViewBridge.shared.currentController() === coordinator {
|
||
|
|
XWebViewBridge.shared.setController(nil)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@MainActor
|
||
|
|
public final class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate, XWebViewController {
|
||
|
|
private weak var webView: WKWebView?
|
||
|
|
|
||
|
|
func attach(_ webView: WKWebView) {
|
||
|
|
self.webView = webView
|
||
|
|
}
|
||
|
|
|
||
|
|
func detach() {
|
||
|
|
webView = nil
|
||
|
|
}
|
||
|
|
|
||
|
|
public func canGoBack() -> Bool {
|
||
|
|
webView?.canGoBack == true
|
||
|
|
}
|
||
|
|
|
||
|
|
public func canGoForward() -> Bool {
|
||
|
|
webView?.canGoForward == true
|
||
|
|
}
|
||
|
|
|
||
|
|
public func currentUrl() -> String? {
|
||
|
|
webView?.url?.absoluteString
|
||
|
|
}
|
||
|
|
|
||
|
|
public func goBack() {
|
||
|
|
webView?.goBack()
|
||
|
|
}
|
||
|
|
|
||
|
|
public func goForward() {
|
||
|
|
webView?.goForward()
|
||
|
|
}
|
||
|
|
|
||
|
|
public func reload() {
|
||
|
|
webView?.reload()
|
||
|
|
}
|
||
|
|
|
||
|
|
public func load(url: String) {
|
||
|
|
guard let url = URL(string: url) else { return }
|
||
|
|
webView?.load(URLRequest(url: url))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#else
|
||
|
|
|
||
|
|
public struct XWebViewView: View {
|
||
|
|
private let config: XWebViewConfig
|
||
|
|
|
||
|
|
public init(config: XWebViewConfig? = nil) {
|
||
|
|
self.config = config ?? XWebViewBridge.shared.currentConfig()
|
||
|
|
}
|
||
|
|
|
||
|
|
public var body: some View {
|
||
|
|
VStack(spacing: 12) {
|
||
|
|
Text(config.title.isEmpty ? "WebView" : config.title)
|
||
|
|
.font(.headline)
|
||
|
|
Text("XWebView is available on iOS with UIKit-backed WebView.")
|
||
|
|
.font(.subheadline)
|
||
|
|
.foregroundStyle(.secondary)
|
||
|
|
}
|
||
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|