使用 WKWebView 的 SwiftUI Webview 因 EXC_BREAKPOINT 而崩溃

问题描述 投票:0回答:1

我在 SwiftUI 中使用 UIViewRepresentable 和 WKWebView 编写了一个 webview。 该应用程序目前已发布在应用程序商店中。对于某些用户来说,应用程序崩溃了,我们无法重现它。

以下是崩溃日志:

Crashed: com.apple.main-thread
EXC_BREAKPOINT 0x000000010455c388
    0  uMove                          0x28388 specialized WebView.makeUIView(context:) + 31 (WebView.swift:31)
    1  uMove                          0x27b48 protocol witness for UIViewRepresentable.makeUIView(context:) in conformance WebView + 4329765704 (<compiler-generated>:4329765704)
    2  SwiftUI                        0xaa4bc OUTLINED_FUNCTION_326 + 6512
    3  SwiftUI                        0x9ac5c OUTLINED_FUNCTION_1106 + 1428
    4  SwiftUI                        0xca31a8 OUTLINED_FUNCTION_1 + 8712
    5  SwiftUI                        0xca5868 OUTLINED_FUNCTION_1 + 18632
    6  SwiftUI                        0x89200 OUTLINED_FUNCTION_513 + 11236
    7  SwiftUI                        0xca306c OUTLINED_FUNCTION_1 + 8396
    8  SwiftUI                        0xca24b8 OUTLINED_FUNCTION_1 + 5400
    9  SwiftUI                        0x53eb00 OUTLINED_FUNCTION_5 + 26880
    10 AttributeGraph                 0x3ef8 AG::Graph::UpdateStack::update() + 512

下面是崩溃的代码片段:从 makeUIView() 函数返回 WKWebView 实例时发生崩溃。

struct WebView: UIViewRepresentable {
    @Binding var url: String
     
    private let wKWebView = WKWebView()
    
    func makeUIView(context: Context) -> WKWebView {
        configure(context: context)
        
        print(LOG_TAG, "makeUIView Webview loading url \(url)")
        if(!url.isEmpty) {
            wKWebView.load(URLRequest(url: URL(string:url)!))
         }
        return wKWebView
    }
    
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        
    }
    
    func makeCoordinator() -> WebViewNavigationDelegate {
        WebViewNavigationDelegate(self)
    }
    
    // Our own methods
    func configure(context: Context) {
        wKWebView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
        //wKWebView.configuration.preferences.javaScriptEnabled = true
        wKWebView.configuration.defaultWebpagePreferences.allowsContentJavaScript = true
        
        wKWebView.allowsBackForwardNavigationGestures = true
        wKWebView.allowsLinkPreview = true
        
        wKWebView.navigationDelegate = context.coordinator
        wKWebView.uiDelegate = context.coordinator
    }
    .....
    ....
    ....
}

最初我认为问题可能是由于在

makeUIView()
函数中加载 URL 造成的,考虑到视图可能尚未准备好,而我们正在尝试加载。所以我将加载 URL 逻辑移至
updateUIView
函数,但没有成功。

ios swiftui crash wkwebview uiviewrepresentable
1个回答
0
投票

从您提供的详细信息来看,您的 WKWebView 实现似乎导致了难以重现的崩溃。

第一个潜在问题是

makeUIView()
中 URL 的强制解包。应避免强制展开 (!),因为如果
URL(string: url)
返回
nil
,应用程序将崩溃。为了安全地处理这个问题,请使用可选的绑定:

if let urlString = URL(string: url) {
     wKWebView.load(URLRequest(url: urlString))
}

此外,直接在

WKWebView
结构中创建
WebView
实例可能会出现问题,特别是在视图生命周期处理不当的情况下。因此,请考虑在
WKWebView
方法中创建
makeUIView
实例。这确保每次创建视图时
WebView
都会被重新初始化,这会更可靠:

func makeUIView(context: Context) -> WKWebView {
    let webView = WKWebView()
    configure(webView: webView, context: context)
    if let url = URL(string: self.url) {
         webView.load(URLRequest(url: URL))
    }
    return webView
}

并更新

configure
方法以接受
WKWebView
参数。

func configure(webView: WKWebView, context: Context) {
    webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
    webView.configuration.defaultWebpagePreferences.allowsContentJavaScript = true

    webView.allowsBackForwardNavigationGestures = true
    webView.allowsLinkPreview = true

    webView.navigationDelegate = context.coordinator
    webView.uiDelegate = context.coordinator
}

最后,我想说你应该确保 WebView 的生命周期在 SwiftUI 中得到正确管理。如果

updateUIView
方法为空,则当视图状态更改时,它可能会丢失关键更新。虽然它与崩溃没有直接关系,但在此处处理视图更新是一个很好的做法。

© www.soinside.com 2019 - 2024. All rights reserved.