解雇前调用WKWebView completionHandler

har*_*man 4 objective-c ios 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();
}
Run Code Online (Sandbox Code Playgroud)

根据苹果的文档,我们应该叫警报的compeletionHandler()压警觉后OK按钮,提到这里

按下OK按钮后如何调用completionHandler()?如果我没有调用completionHandler(),则抛出expect

**[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'****
Run Code Online (Sandbox Code Playgroud)

更新:

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];
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ntz 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];
Run Code Online (Sandbox Code Playgroud)

这将显示警报并completionHandler在用户解除警报时调用.

请注意,我使用的UIAlertController是,仅在iOS 8及更高版本上可用,但是因为你依赖它应该没问题WKWebView.

  • 这很明显.你不要调用presentViewController. (3认同)