WKWebView completionHandler 在解雇前调用
WKWebView completionHandler called before dismissal
我正在使用 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 上运行不佳。以下是我得到相同异常的代码,即使在确定和取消按钮中调用了 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];
}
您现在的代码设置方式,您立即显示 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
.
我正在使用 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 上运行不佳。以下是我得到相同异常的代码,即使在确定和取消按钮中调用了 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];
}
您现在的代码设置方式,您立即显示 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
.