如何解决使用 WKWebView 通过 SwiftUI 从任何页面同步数据 - 但有更好的方法吗?
在下面的代码中,我将 HTML 页面加载到 WKWebView 中,只是为了获取它们的第一个 H1 标签的内容。除了任何类型的页面在其第一个 H1 标签中呈现的内容之外,我不需要任何其他内容......
除了为此初始化 WKWebView 之外,是否还有更高效/性能更好的方法?
(.frame(width: 0,height: 0)
修饰符也让我有点恼火)
import SwiftUI
import WebKit
import WebView /* add this Swift Package Dependency https://github.com/kylehickinson/SwiftUI-WebView */
struct ContentView: View {
@StateObject private var viewModel: ContentViewModel
init() {
let viewModel = ContentViewModel()
_viewModel = StateObject(wrappedValue: viewModel)
}
var body: some View {
VStack(spacing: 30) {
Button("load plain H1 tag") {
viewModel.webViewStore.webView.loadHTMLString("<h1>H1</h1>",baseURL: nil)
}
Button("load body where h1 is appended by JavaScript") {
viewModel.webViewStore.webView.loadHTMLString("<body></body><script>(function(){ let h1 = document.createElement('h1'); h1.textContent = 'H1 JavaScript'; document.body.appendChild(h1); })()</script>",baseURL: nil)
}
Button("load apple.com/iphone") {
viewModel.webViewStore.webView.load(URLRequest(url: URL(string: "https://apple.com/iphone")!))
}
Button("load hackingwithswift.com") {
viewModel.webViewStore.webView.load(URLRequest(url: URL(string: "https://hackingwithswift.com")!))
}
Group {
Text("the first H1 element on ")
+ Text(viewModel.webViewStore.webView.url?.description ?? "...").foregroundColor(.accentColor)
+ Text(" is")
}
.font(.subheadline)
Text(viewModel.h1)
.font(.largeTitle)
.foregroundColor(.green)
WebView(webView: viewModel.webViewStore.webView)
.frame(width: 0,height: 0)
}
}
}
class ContentViewModel: NSObject,WKScriptMessageHandler,ObservableObject {
@Published var h1 = "..."
@Published var webViewStore: WebViewStore
override init() {
let userContentController = WKUserContentController()
let configuration = WKWebViewConfiguration()
let userScript = WKUserScript(
source: """
function elementReady(selector) {
return new Promise((resolve,reject) => {
let el = document.querySelector(selector)
if (el) {
resolve(el)
}
new MutationObserver((mutationRecords,observer) => {
Array.from(document.querySelectorAll(selector)).forEach((element) => {
resolve(element)
observer.disconnect()
})
}).observe(document.documentElement,{
childList: true,subtree: true,})
})
}
elementReady("h1").then((titleElement) => {
window.webkit.messageHandlers.h1.postMessage(titleElement.textContent)
})
""",injectionTime: .atDocumentStart,forMainFrameOnly: false,in: .defaultClient
)
userContentController.addUserScript(userScript)
configuration.userContentController = userContentController
let webView = WKWebView(frame: .zero,configuration: configuration)
webViewStore = WebViewStore(webView: webView)
super.init()
userContentController.add(self,contentWorld: .defaultClient,name: "h1")
}
func userContentController(_ userContentController: WKUserContentController,didReceive message: WKScriptMessage) {
if message.name == "h1" {
h1 = message.body as! String
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。