【问题标题】:WKWebView completionHandler called before dismissalWKWebView completionHandler 在解雇之前调用
【发布时间】:2015-10-01 15:50:19
【问题描述】:

我正在使用 WKUIDelegate 这个函数来处理 javascript 警报

-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{

    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Test Alert", nil)
                                                     message:message
                                                    delegate:self
                                           cancelButtonTitle:nil
                                           otherButtonTitles:@"OK", nil] autorelease];

    [alert show];
    completionHandler();
}

根据 Apple 文档,我们应该在警报按下 OK 按钮后调用警报的 compeletionHandler(),如提到的 here

按下OK按钮后如何调用completionHandler()?如果我不调用 completionHandler() 就会抛出期望

**[WKWebViewController webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:
    completionHandler:]:
***** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
   reason: 'Completion handler passed to -[WKWebViewController
   webView:runJavaScriptAlertPanelWithMessage:
   initiatedByFrame:completionHandler:] was not called'****

更新:

Stefan 下面提到的解决方案适用于 JS Alert,但不适用于 JS Confirm。以下是我得到相同异常的代码,即使在 ok 中调用了 completionHandler() 并取消按钮。

-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
{
    MKCLOG_DEBUG(@"%@", frame.request.URL);
    UIAlertController* alert = [UIAlertController alertControllerWithTitle:
                                NSLocalizedString(@"Test", nil) message: message
                                                            preferredStyle: UIAlertControllerStyleAlert];

    UIAlertAction *cancelAction = [UIAlertAction
                                   actionWithTitle:NSLocalizedString(@"Cancel", @"")
                                   style:UIAlertActionStyleCancel
                                   handler:^(UIAlertAction *action)
                                   {
                                       MKCLOG_DEBUG(@"Cancel action");
                                       completionHandler(NO);
                                   }];

    UIAlertAction *okAction = [UIAlertAction
                               actionWithTitle:NSLocalizedString(@"OK", @"OK action")
                               style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction *action)
                               {
                                   MKCLOG_DEBUG(@"OK action");
                                   completionHandler(YES);
                               }];

    [alert addAction:cancelAction];
    [alert addAction:okAction];
}

【问题讨论】:

  • 你不要在JS Confirm方法中调用presentViewController。添加此行以修复[self presentViewController:alert animated:YES completion:nil];

标签: ios objective-c wkwebview wkwebviewconfiguration


【解决方案1】:

现在设置代码的方式是显示UIAlertView,然后立即运行completionHandler()。两者同时发生。

你应该做的是这样的:

UIAlertController* alert = [UIAlertController alertControllerWithTitle:
    NSLocalizedString(@"Test Alert", nil) message: message
        preferredStyle: UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle: @"OK"
    style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
      completionHandler();
}]; 
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];

这将显示警报并在用户关闭它时调用completionHandler

请注意,我使用的是 UIAlertController,它仅适用于 iOS 8 及更高版本,但这应该没问题,因为您依赖于 WKWebView

【讨论】:

  • 感谢您的回复,上面的代码适用于 JS 警报处理,但不适用于 JS Confirm。知道该怎么做吗?
  • 只需为取消按钮添加另一个 UIAlertAction。与上面相同,但具有不同的标题和对完成处理程序的正确调用。如果您需要帮助,请发布代码。
  • 这很明显。您不调用 presentViewController。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
相关资源
最近更新 更多