WKWebView:应用程序因“NSInternalInconsistencyException”异常而崩溃,因为“未调用传递给 X 的完成处理程序”

Posted

技术标签:

【中文标题】WKWebView:应用程序因“NSInternalInconsistencyException”异常而崩溃,因为“未调用传递给 X 的完成处理程序”【英文标题】:WKWebView: App crashing with 'NSInternalInconsistencyException' exception because 'Completion handler passed to X was not called' 【发布时间】:2017-12-23 08:55:54 【问题描述】:

当尝试在 ios 上的 WKWebView 中同时显示两个 javascript 警报框时,会发生以下异常。应用程序因此崩溃。

2017-12-23 00:46:29.434 Couch[3192:3428809] *** 由于以下原因而终止应用程序 未捕获的异常“NSInternalInconsistencyException”,原因: '完成处理程序传递给 -[XViewController webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:] 没有被调用'

这是有问题的 WKWebView 委托函数:

func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
             completionHandler: @escaping () -> Void) 

    let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler:  (action) in
        completionHandler()
    ))

    if let presenter = alertController.popoverPresentationController 
        presenter.sourceView = self.view
        presenter.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
    
    if presentedViewController == nil 
        present(alertController, animated: true, completion: nil)
    

【问题讨论】:

【参考方案1】:

在第一个UIAlertController 出现后,presentedViewController 不再是nil。然后您的委托方法不会显示第二个/下一个 UIAlertController 并静默返回。但是,您仍然需要致电completionHandler()

if presentedViewController == nil

    // You get here for the second alert box, which is not shown.
    present(alertController, animated: true, completion: nil)

else

    completionHandler()

第二个,第三个,...UIAlertController 永远不会出现。如果这不是您想要的,请查看here。

【讨论】:

有意思,试试这个! 不幸的是,它没有用。由于某种原因,第二个警报甚至没有调用 else 条件。 (我们在函数的 else 条件和更高的位置设置了一个断点。) 第一个和第二个警报没有出现在屏幕上对吗?也许presentedViewController 设置得稍晚一些。作为一个实验,您可以将var isPresented: Bool = false 添加到您的类中,将其设置在present(alertController, animated: true, completion: nil) 上方,并将我的代码更改为if !isPresented。当然,在addAction 的块中适当地重置isPresented 正确,第一个警报出现。单击显示警报的按钮是导致应用程序崩溃的原因。感谢您的帮助! 实验完成了什么?由于某种原因,整个函数没有被第二次调用,这对这种情况有帮助吗?再次感谢您的帮助!

以上是关于WKWebView:应用程序因“NSInternalInconsistencyException”异常而崩溃,因为“未调用传递给 X 的完成处理程序”的主要内容,如果未能解决你的问题,请参考以下文章

带有位置服务的 wkwebview

如何创建两个 WkWebView

WKWebView:页面加载后调用javascript

WebKit webview (WKwebview) 无法加载应用目录之外的资源

基于cordova的应用程序中的Wkwebview实现

在 iOS 应用中更改 WKWebView 的来源