Görünüm yapısında üyeyi başlat
SwiftUI'de JavaScript işlemeli bir WKWebView'a sahip olmak istiyorum. Gönderen Swift Değişkenler Başlatma , ben aşağıdakileri yapıyorum: (kullanıyorumhttps://github.com/kylehickinson/SwiftUI-WebViewWKWebView
SwiftUI için değerli düzen kısıtlamaları da ekleyen bir sarmalayıcı sağlamak .)
struct ContentView: View {
var body: some View {
WebView(webView: myWebView)
.onAppear {
let url = Bundle.main.url(forResource: "index", withExtension: "html")!
myWebView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
myWebView.load(request)
}
}
class JSHandler : NSObject, WKScriptMessageHandler {
var contentView: ContentView?
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("documentReady")
contentView!.myWebView.evaluateJavaScript("<Long Script to Transfer Data>") { (result, error) in
}
}
}
let myJSHandler = JSHandler()
var myWebView: WKWebView = {
let config = WKWebViewConfiguration()
let controller = WKUserContentController()
controller.add(myJSHandler , name: "documentReady")
config.userContentController = controller
return WKWebView(frame: .zero, configuration: config)
}()
}
Ancak daha sonra Instance üyesinden , kapanışın self'e referansı olmadığı için çalışmadığını tür üzerinde kullanılamayacağını öğrendim . WKWebView'a adanmış yapılandırma nesnesine ihtiyacım var, bu yüzden diğer kurucuyu kullanamam. Yapmak için bir referansa ihtiyacım var evaluateJavaScript
.
Bu nasıl çalışır?
DÜZENLEME 1 : body
WKWebView'ı sarmak için kullanılan çerçeveyi ekleyin ve bahsedin.
DÜZENLEME 2 : WKWebView
Yerel uygulamadan WKScriptMessageHandler
(HTML belgesi hazır olduğunda bildirim almak için) ve yerel uygulamadan WKWebView
yoluyla evaluateJavaScript
(HTML belgesi hazır olduğunda verileri aktarmak için) iki yönlü iletişime ihtiyacım olduğunu açıklığa kavuşturmak için kod eklendi .
Yanıtlar
Olası bir çözüm, WKWebView'ı init
struct ContentView: View {
private var myWebView: WKWebView
init() {
let config = WKWebViewConfiguration()
let controller = WKUserContentController()
controller.add(myJSHandler , name: "documentReady")
config.userContentController = controller
myWebView = WKWebView(frame: .zero, configuration: config)
}
var body: some View {
WebView(webView: myWebView)
.onAppear {
let url = Bundle.main.url(forResource: "index", withExtension: "html")!
myWebView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
myWebView.load(request)
}
}
class JSHandler : NSObject, WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("documentReady")
message.webView?.evaluateJavaScript("<Long Script to Transfer Data>") { (result, error) in
}
}
}
let myJSHandler = JSHandler()
}
Sadece myWebView bir lazy
değişken yapın. Bu, jsHandler'ın WebView'dan önce başlatıldığından emin olmanızı sağlar.
lazy var myWebView: WKWebView = {
let config = WKWebViewConfiguration()
let controller = WKUserContentController()
controller.add(myJSHandler , name: "documentReady")
config.userContentController = controller
return WKWebView(frame: .zero, configuration: config)
}()