【发布时间】:2019-12-18 22:16:43
【问题描述】:
我正在使用 SwiftUI 构建一个简单的 webapp,它只是将我的网站加载到 webview 中。在我的网站上,它必须显示 Javascript confirm 以便用户能够从应用程序中注销,并且我在 runJavaScriptConfirmPanelWithMessage 中的函数在触发 Javascript 确认时会导致应用程序崩溃。
这是我的 webapp 的完整代码。
import SwiftUI
import WebKit
struct Webview : UIViewRepresentable {
let request: URLRequest
var webview: WKWebView?
init(web: WKWebView?, req: URLRequest) {
self.webview = WKWebView()
self.request = req
}
class Coordinator: NSObject, WKUIDelegate {
var parent: Webview
init(_ parent: Webview) {
self.parent = parent
}
// Delegate methods go here
func webView(_ webView: WKWebView,
runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
// alert functionality goes here
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
alertController.present(alertController, animated: true)
completionHandler()
}
func webView(_ webView: WKWebView,
runJavaScriptConfirmPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (Bool) -> Void) {
// confirm functionality goes here. THIS CRASHES THE APP
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
completionHandler(true)
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
completionHandler(false)
}))
alertController.present(alertController, animated: true, completion: nil)
}
func webView(_ webView: WKWebView,
runJavaScriptTextInputPanelWithPrompt prompt: String,
defaultText: String?,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (String?) -> Void) {
// prompt functionality goes here
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
return webview!
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.uiDelegate = context.coordinator
uiView.load(request)
}
func goBack(){
webview?.goBack()
}
func goForward(){
webview?.goForward()
}
func reload(){
webview?.reload()
}
}
struct ContentView: View {
let webview = Webview(web: nil, req: URLRequest(url: URL(string: "https://google.com")!))
var body: some View {
VStack {
webview
HStack() {
Button(action: {
self.webview.goBack()
}){
Image(systemName: "chevron.left")
}.padding(32)
Button(action: {
self.webview.reload()
}){
Image(systemName: "arrow.clockwise")
}.padding(32)
Button(action: {
self.webview.goForward()
}){
Image(systemName: "chevron.right")
}.padding(32)
}.frame(height: 40)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我不确定我在本节中对导致应用程序崩溃的runJavaScriptConfirmPanelWithMessage 做错了什么。
这是我遇到问题的部分。
func webView(_ webView: WKWebView,
runJavaScriptConfirmPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (Bool) -> Void) {
// confirm functionality goes here. THIS CRASHES THE APP
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
completionHandler(true)
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
completionHandler(false)
}))
alertController.present(alertController, animated: true, completion: nil)
}
谁能告诉我我在这里做错了什么?
【问题讨论】:
-
您必须在此工作流程中使用 SwiftUI
Alert。我会通过Webview周围的附加包装器来实现,并绑定到当前警报,可能还有附加视图模型来传输 JS 警报参数。 -
@Asperi 感谢您的评论。您的意思是我需要将 Javascript Alert 映射到 SwiftUI alert(developer.apple.com/documentation/swiftui/alert) 才能完成这项工作?那么 Confirm 也一样吗?
-
是的,这些警报应该通过 SwiftUI
View.alert函数呈现