WKWebView 遇到 NSInternalInconsistencyException runJavaScriptAlertPanelWithMessage: was not called

68 篇文章 1 订阅

WKWebView 遇到 NSInternalInconsistencyException runJavaScriptAlertPanelWithMessage: was not called

Completion handler passed to -[xxx.BaseWebViewController webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:] was not called

从 crash 可以看出是 WKWebView 回调函数: runJavaScriptAlertPanelWithMessage中completionHandler 没有被调用导致的。

出现情况可能是WKWebView 退出的时候,JS刚好执行了window.alert(), alert 框可能弹不出来,completionHandler 最后没有被执行,导致 crash;另一种情况是在 WKWebView 一打开,JS就执行window.alert(),这个时候由于 WKWebView 所在的 UIViewController 出现(push或present)的动画尚未结束,alert 框可能弹不出来,completionHandler 最后没有被执行,导致 crash。

解决办法如下:

#pragma mark -- WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    if ([self.navigationController visibleViewController] != self)
    {
        completionHandler();
        return;
    }
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        completionHandler();
        
    }]];
    if ([self.navigationController visibleViewController] == self)    {
        [self presentViewController:alertController animated:YES completion:nil];
    }else
    {
        completionHandler();
    }
    
}
// 显示两个按钮,通过completionHandler回调判断客户点击确实定还是取消按钮
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    if ([self.navigationController visibleViewController] != self)    {
        completionHandler(NO);
        return;
    }
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
        
    }]];
    [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }]];
    if ([self.navigationController visibleViewController] == self)    {
        [self presentViewController:alertController animated:YES completion:nil];
    }else{
        completionHandler(NO);
    }
    
}
// 显示一个带有输入框和一个确定按钮的,通过completionHandler回调客户输入的内容
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    if ([self.navigationController visibleViewController] != self)    {
        completionHandler(@"error");
        return;
    }
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:nil preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        
    }];
    [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alertController.textFields.lastObject.text);
        
    }]];
    if ([self.navigationController visibleViewController] == self)    {
        [self presentViewController:alertController animated:YES completion:nil];
        
    }
    else
    {
        completionHandler(@"error");
        
    }
    
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 这是一个错误信息,意思是在未连接状态下,没有调用qnativesocketengine::bind()函数。qnativesocketengine是Qt中的一个底层网络引擎,用于实现网络通信功能。qabstractsocket是Qt中的一个抽象套接字类,用于封装不同平台的套接字实现。在使用qabstractsocket进行网络通信时,需要先调用bind()函数来绑定本地地址和端口,然后再调用connect()函数来连接远程地址和端口。如果在未连接状态下没有调用bind()函数,就会出现上述错误。 ### 回答2: qAbstractSocket是Qt网络编程中的一个基础类,用于实现TCP和UDP socket通信。在使用qAbstractSocket时,有时候会出现 “qnativesocketengine::bind() was not called in qabstractsocket::unconnectedstate”的错误提示。这个错误提示一般是由以下原因造成的: 1. 没有调用bind()函数:在使用qAbstractSocket时,如果没有调用bind()函数,那么就会出现这个错误提示。bind()函数用于将socket绑定到指定的IP地址和端口号,这是连接其他主机时必须要做的。如果没有调用bind()函数,那么socket就没有绑定到任何地址和端口上,就无法进行其他操作,就会出现这个错误提示。 2. 调用错误的函数:在使用qAbstractSocket时,如果调用了错误的函数,也会导致这个错误提示的出现。比如,调用了connectToHost()函数同时又调用了write()函数,由于connectToHost()函数是异步的,所以write()函数执行时,socket还没有连接上主机,就会出现这个错误提示。 3. 网络故障:在使用qAbstractSocket时,如果网络故障,导致连接失败,也会出现这个错误提示。网络故障包括主机不可达、端口不可用等情况。如果发现这种错误提示,可以检查网络连接是否正常,是否设置了正确的IP地址和端口号等。 如果出现了qnativesocketengine::bind() was not called in qabstractsocket::unconnectedstate的错误提示,可以仔细检查自己的程序,看看是不是遇到了上述情况。如果问题无法解决,也可以参考Qt的官方文档或者向Qt社区求助。 ### 回答3: qabstractsocket::unconnectedstate表示Qt中继承自抽象套接字类(QAbstractSocket)的套接字处于未连接状态。在这个状态下,qnativesocketengine::bind()必须被调用,以便为套接字分配本地地址和端口。如果没有调用这个函数,并且试图在未连接状态下建立连接,则会出现问题。 具体来说,如果在未连接状态下尝试使用QAbstractSocket::connectToHost()方法,Qt将调用QNativeSocketEngine :: bind()方法来绑定套接字。如果没有调用此方法,则QAbstractSocket::connectToHost()将无法绑定套接字并建立连接。结果,将会抛出“qnativesocketengine :: bind()was not called in qabstractsocket :: unconnectedstate”异常。 同样,在未连接状态下,如果尝试使用QAbstractSocket :: bind()方法绑定套接字,则需要事先调用QNativeSocketEngine :: bind()函数。否则,将出现类似的异常。 为解决这个问题,开发者需要在使用QAbstractSocket之前调用QNativeSocketEngine :: bind()方法。此外,应确保套接字处于未连接状态,以便在调用QNativeSocketEngine :: bind()时能够成功绑定。如果已经处于连接状态,则应使用QAbstractSocket :: disconnectFromHost()方法断开连接。 对于使用Qt的开发者来说,遵循这些步骤是很重要的,以确保他们成功地在未连接状态下使用套接字进行通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WMSmile

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值