iOS WKWebView冷启动后显示about:blank问题解决求助
冷启动后WKWebView显示
about:blank的排查与解决 问题背景
iOS应用中使用WKWebView加载网页,后台或运行状态下加载正常,但强制退出(上滑关闭)后重启,WebView仅显示about:blank空白页;删除重装应用后可恢复正常加载。
相关代码
WebView.swift
struct WebView: UIViewRepresentable { var url: URL? var redirect: ((URL) -> Void)? func makeUIView(context: Context) -> WKWebView { let webView = WKWebView() webView.isInspectable = true webView.navigationDelegate = context.coordinator return webView } func updateUIView(_ webView: WKWebView, context: Context) { if let url = url { webView.load(URLRequest(url: url)) } } func makeCoordinator() -> Coordinator { Coordinator(parent: self) } class Coordinator: NSObject, WKNavigationDelegate { var parent: WebView init(parent: WebView) { self.parent = parent } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { let javascript = """ if (document.querySelector('meta[name="viewport"]')) { document.querySelector('meta[name="viewport"]').setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'); } else { const meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'); document.getElementsByTagName('head')[0].appendChild(meta); } true; """ webView.evaluateJavaScript(javascript) { result, error in if let error = error { print("Error injecting JavaScript: \(error)") } else { print("JavaScript executed successfully.") } } print("WebView finished loading.") } func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { print("WebView failed with error: \(error.localizedDescription)") } func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { print("WebView provisional load failed: \(error.localizedDescription)") } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if let url = navigationAction.request.url, url.scheme == "oauthapp" { parent.redirect?(url) // Pass deep link to your SwiftUI view decisionHandler(.cancel) // Cancel navigation return } decisionHandler(.allow) } } }
ContentView
func buildAuthURL() -> URL? { var components = URLComponents(string: authURL) components?.queryItems = [ URLQueryItem(name: "response_type", value: "code"), URLQueryItem(name: "client_id", value: clientID), URLQueryItem(name: "redirect_uri", value: redirectURI), URLQueryItem(name: "code_challenge", value: codeChallenge), URLQueryItem(name: "code_challenge_method", value: "S256"), URLQueryItem(name: "scope", value: scopes) ] return components?.url } var body: some View { if accessToken == nil { WebView(url: buildAuthURL()){ url in if let components = URLComponents(string: url.absoluteString), let code = components.queryItems?.first(where: { $0.name == "code" })?.value { print("Authorization code: \(code)") authCode = code requestAccessToken(code: code) } else { print("Failed to extract code from URL.") } }.ignoresSafeArea() } else { Text("Authorization Code: \((authCode ?? "").prefix(15))...") Text("Access Token: \((accessToken ?? "").prefix(15))...") } }
问题现象
- 冷启动(强制退出后启动)时,WebView显示空白,地址为
about:blank - 应用无崩溃,其他功能正常
排查与修复方案
1. 验证URL生成是否正常
冷启动时可能authURL、clientID等配置项未完成初始化,导致buildAuthURL()返回nil,updateUIView未执行加载逻辑。
- 调试:在
buildAuthURL()中添加日志,确认URL生成状态:func buildAuthURL() -> URL? { print("Auth URL base: \(authURL ?? "nil")") var components = URLComponents(string: authURL) print("Generated components: \(components ?? nil)") components?.queryItems = [ URLQueryItem(name: "response_type", value: "code"), URLQueryItem(name: "client_id", value: clientID), URLQueryItem(name: "redirect_uri", value: redirectURI), URLQueryItem(name: "code_challenge", value: codeChallenge), URLQueryItem(name: "code_challenge_method", value: "S256"), URLQueryItem(name: "scope", value: scopes) ] print("Final URL: \(components?.url ?? nil)") return components?.url } - 修复:确保
authURL等配置项在冷启动时已从本地存储/配置文件中正确加载,避免依赖运行时动态赋值。
2. 强化WebView初始化时的加载逻辑
SwiftUI的updateUIView可能因冷启动时视图刷新时机问题未触发,导致URL未加载。可在makeUIView中直接添加初始加载逻辑:
func makeUIView(context: Context) -> WKWebView { let webView = WKWebView() webView.isInspectable = true webView.navigationDelegate = context.coordinator // 初始化时直接加载URL,避免依赖updateUIView if let url = url { webView.load(URLRequest(url: url)) } return webView }
同时保留updateUIView中的逻辑,应对后续URL变化场景。
3. 排查异常缓存影响
冷启动时WKWebView可能残留异常缓存,导致加载失败。可临时添加缓存清除逻辑排查:
func makeUIView(context: Context) -> WKWebView { // 清除WKWebView缓存(仅作为排查手段,正式环境按需使用) let websiteDataTypes: Set<String> = [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache] WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes, modifiedSince: .distantPast) { print("Cache cleared") } let webView = WKWebView() webView.isInspectable = true webView.navigationDelegate = context.coordinator if let url = url { webView.load(URLRequest(url: url)) } return webView }
4. 细化错误日志排查
当前错误回调仅打印简单描述,可补充详细错误信息定位问题:
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { let nsError = error as NSError print("Provisional load failed: \(error.localizedDescription) | Code: \(nsError.code) | Domain: \(nsError.domain)") }
常见冷启动错误包括:ATS配置未授权网络请求、证书信任问题、URL Scheme未正确配置等,可根据错误码针对性处理。
内容的提问来源于stack exchange,提问作者Source
相关产品推荐
相关产品推荐

