解雇前调用WKWebView completionHandler

时间:2015-10-01 15:50:19

标签: ios objective-c wkwebview wkwebviewconfiguration

我正在使用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()[{3}}

按下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和cancel按钮中调用了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];
}

1 个答案:

答案 0 :(得分:5)

现在设置代码的方式,您显示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,因此应该没问题。