admin管理员组文章数量:1134247
I am having some trouble getting a WKWebView in iOS 8 to display an alert dialog that is called from Javascript. After creating a standard WKWebView and loading an HTML file, I have a button on the page that creates a simple alert with some text. This works in UIWebView and in Google Chrome/Safari, but does not appear to be working in WKWebView. Any help is appreciated.
My setup is as follows:
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.allowsInlineMediaPlayback = YES;
config.mediaPlaybackRequiresUserAction = false;
_wkViewWeb = [[WKWebView alloc] initWithFrame:_viewWeb.frame config];
_wkViewWeb.scrollView.scrollEnabled = NO;
NSString *fullURL = @"file://.../TestSlide.html";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[_wkViewWeb loadRequest:request];
The html has the following function:
<SCRIPT Language="JavaScript">
function alertTest() {
alert("Testing Alerts");
}
</SCRIPT>
And a button:
<b>Test Alerts: <input type="button" value="Alert Popup" onclick="alertTest()"><br></b> <br>
This setup works in UIWebView and in regular browsers, but does not work in WKWebView. Am I missing something in the configuration? Should I be using one of the WK delegates to control the alert/confirm dialog behavior? Thank you.
I am having some trouble getting a WKWebView in iOS 8 to display an alert dialog that is called from Javascript. After creating a standard WKWebView and loading an HTML file, I have a button on the page that creates a simple alert with some text. This works in UIWebView and in Google Chrome/Safari, but does not appear to be working in WKWebView. Any help is appreciated.
My setup is as follows:
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.allowsInlineMediaPlayback = YES;
config.mediaPlaybackRequiresUserAction = false;
_wkViewWeb = [[WKWebView alloc] initWithFrame:_viewWeb.frame config];
_wkViewWeb.scrollView.scrollEnabled = NO;
NSString *fullURL = @"file://.../TestSlide.html";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[_wkViewWeb loadRequest:request];
The html has the following function:
<SCRIPT Language="JavaScript">
function alertTest() {
alert("Testing Alerts");
}
</SCRIPT>
And a button:
<b>Test Alerts: <input type="button" value="Alert Popup" onclick="alertTest()"><br></b> <br>
This setup works in UIWebView and in regular browsers, but does not work in WKWebView. Am I missing something in the configuration? Should I be using one of the WK delegates to control the alert/confirm dialog behavior? Thank you.
Share Improve this question asked Nov 12, 2014 at 23:55 CharlieCharlie 8431 gold badge6 silver badges5 bronze badges 2- can u try hosting the html file and try "http://" instead of "file://", it may be because of this bug in wkwebview: openradar.me/radar?id=5839348817723392 – krisrak Commented Nov 13, 2014 at 19:21
- The html files are stored locally so they can be accessed offline. The file loads without an issue, its only the alert dialog that does not display when the button is tapped. – Charlie Commented Nov 13, 2014 at 23:04
7 Answers
Reset to default 95To solve this you need a WKUIDelegate for your web view. It is the duty of the delegate to decide if an alert should be displayed, and in what way. You need to implement this for alert, confirm and text input (prompt).
Here is sample code without any validation of the page url or security features:
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
More in the Official Documentation
Swift 3 with all 3 optional functions implemented:
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
completionHandler()
}))
present(alertController, animated: true, completion: nil)
}
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (Bool) -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
completionHandler(true)
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
completionHandler(false)
}))
present(alertController, animated: true, completion: nil)
}
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (String?) -> Void) {
let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: .actionSheet)
alertController.addTextField { (textField) in
textField.text = defaultText
}
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
if let text = alertController.textFields?.first?.text {
completionHandler(text)
} else {
completionHandler(defaultText)
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
completionHandler(nil)
}))
present(alertController, animated: true, completion: nil)
}
Just to expand a bit, WKWebView
requires you to show alerts, prompts, and confirms yourself. Do this by becoming a WKUIDelegate
:
#import <WebKit/WebKit.h>
@interface MyController : UIViewController<WKUIDelegate>
Then assign the delegate:
web.UIDelegate = self;
Then you need to actually implement alert, prompt, and confirm. I create WKWebViewPanelManager.h/m as an easy implementation, so here's what I do:
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
[WKWebViewPanelManager presentAlertOnController:self.view.window.rootViewController title:@"Alert" message:message handler:completionHandler];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
[WKWebViewPanelManager presentConfirmOnController:self.view.window.rootViewController title:@"Confirm" message:message handler:completionHandler];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
[WKWebViewPanelManager presentPromptOnController:self.view.window.rootViewController title:@"Prompt" message:prompt defaultText:defaultText handler:completionHandler];
}
Of course, it's up to you to filter out bad alert/confirm/prompt requests.
And here's that in swift:
func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: message,
message: nil,
preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .cancel) {
_ in completionHandler()}
)
self.present(alertController, animated: true, completion: nil)
}
- Implement the protocol to your WKWebview container controller. WKUIDelegate
Add preference to WKWebview to enable javascript in viewDidLoad() as.
// enable JS webView.configuration.preferences.javaScriptEnabled = true
Register WKWebview UI Delegate in viewDidLoad() as
self.webView.uiDelegate = self
Implement the below delegate in your class.
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { let alertController = UIAlertController(title: message,message: nil,preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "OK", style: .cancel) {_ in completionHandler()}) self.present(alertController, animated: true, completion: nil) }
Here is the code in Swift 4.2
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: message, message: nil,
preferredStyle: UIAlertController.Style.alert);
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.cancel) {
_ in completionHandler()}
);
self.present(alertController, animated: true, completion: {});
}
- The viewController
ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate
- Enable JavaScript
webView.configuration.preferences.javaScriptEnabled = true
- In the ViewDidLoad() Function add the below items
webView.uiDelegate = self
webView.navigationDelegate = self
view.addSubview(webView)
- Add the delegate as follows
func webView(_ webView: WKWebView,
runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
let title = NSLocalizedString("OK", comment: "OK Button")
let ok = UIAlertAction(title: title, style: .default) { (action: UIAlertAction) -> Void in
alert.dismiss(animated: true, completion: nil)
}
alert.addAction(ok)
present(alert, animated: true)
completionHandler()
}
本文标签: iOS WKWebView not showing javascript alert() dialogStack Overflow
版权声明:本文标题:iOS WKWebView not showing javascript alert() dialog - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736857382a1955770.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论