You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中WKWebView无法弹出Alert的问题排查求助

问题原因

控制台核心错误提示:Attempt to present <SwiftUI.PlatformAlertController> ... which is already presenting <_TtGC7SwiftUI29PresentationHostingController>,说明你试图在已经弹出fullScreenCover模态视图的父视图上展示Alert,而iOS不允许一个视图控制器同时present两个模态视图,导致Alert无法显示。

解决方案

将Alert的状态和展示逻辑从父视图(ContentView)移到fullScreenCover内部的视图层级中,让Alert属于当前显示的模态视图,而非父视图。同时确保UI操作在主线程执行。

步骤1:创建WebView容器视图

新增WebViewContainer视图,封装WebView和对应的Alert逻辑:

struct WebViewContainer: View {
    let urlString: String
    @State private var showError = false
    @State private var errorMessage = ""
    
    var body: some View {
        if let url = URL(string: urlString) {
            WebView(url: url) { error in
                // 确保在主线程更新UI状态
                DispatchQueue.main.async {
                    errorMessage = error
                    showError = true
                }
            }
        } else {
            Text("not valid url")
        }
        // 将Alert附加到当前模态视图
        .alert(isPresented: $showError) {
            Alert(title: Text("Error"), message: Text(errorMessage), dismissButton: .default(Text("OK")))
        }
    }
}

步骤2:修改ContentView的fullScreenCover调用

替换原来的fullScreenCover内容,使用新的容器视图:

struct ContentView: View {
    @State private var showWebView = false
    
    var body: some View {
        Button("open WebView") {
            showWebView = true
        }
        .fullScreenCover(isPresented: $showWebView) {
            WebViewContainer(urlString: "https://www.google.com")
        }
    }
}

步骤3:确保WKNavigationDelegate方法在主线程触发回调

修改WebView Coordinator中的回调逻辑,强制在主线程执行(避免UI操作在后台线程引发的问题):

class Coordinator: NSObject, WKNavigationDelegate {
    var parent: WebView
    
    init(_ parent: WebView) {
        self.parent = parent
    }
    
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        DispatchQueue.main.async {
            self.parent.handleError?(error.localizedDescription)
        }
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        DispatchQueue.main.async {
            self.parent.handleError?("Hello, fake error for testing")
        }
    }
}
额外说明
  • 控制台中的[Security] This method should not be called on the main thread提示,是WKWebView内部的Cookie相关操作(你提到的监控Cookie任务)在主线程执行导致的,后续处理Cookie逻辑时,建议将耗时操作放到后台线程执行,避免UI卡顿。
  • iOS 15的SwiftUI模态视图层级管理严格,所有模态相关的UI操作(如Alert、Sheet)必须附加到当前活跃的模态视图上,不能跨层级触发。

内容的提问来源于stack exchange,提问作者biggreentree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 13:44:52