web-dev-qa-db-ja.com

iOSのWKWebViewにjavascript alert()ダイアログが表示されない

IOS 8でWKWebViewを取得して、Javascriptから呼び出される警告ダイアログを表示するのに問題があります。標準のWKWebViewを作成し、HTMLファイルを読み込んだ後、ページ上にテキスト付きの簡単なアラートを作成するボタンがあります。これはUIWebViewおよびGoogle Chrome/Safariで機能しますが、WKWebViewでは機能していないようです。どんな助けも大歓迎です。

私のセットアップは次のとおりです。

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];

Htmlには次の機能があります。

<SCRIPT Language="JavaScript">
function alertTest() {
    alert("Testing Alerts");
}
</SCRIPT>

そしてボタン:

<b>Test Alerts: <input type="button" value="Alert Popup" onclick="alertTest()"><br></b> <br>

このセットアップは、UIWebViewおよび通常のブラウザーでは機能しますが、WKWebViewでは機能しません。構成に何か不足していますか? WKデリゲートの1つを使用して、アラート/確認ダイアログの動作を制御する必要がありますか?ありがとうございます。

55
Charlie

これを解決するには、WebビューにWKUIDelegateが必要です。アラートを表示するかどうか、およびその方法を決定するのは、デリゲートの義務です。警告、確認、およびテキスト入力(プロンプト)のためにこれを実装する必要があります。

ページのURLやセキュリティ機能を検証しないサンプルコードを次に示します。

- (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:^{}];
}

公式ドキュメント の詳細

64
Nikola Lajic

Swift 3つのオプション機能すべてが実装されています:

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)
}
40
Crashalot

少し拡張するために、WKWebViewでは、アラート、プロンプト、および確認を表示する必要があります。 WKUIDelegateになることでこれを行います:

#import <WebKit/WebKit.h>
@interface MyController : UIViewController<WKUIDelegate>

次に、デリゲートを割り当てます。

web.UIDelegate = self;

次に、実際にアラート、プロンプト、および確認を実装する必要があります。 WKWebViewPanelManager.h/m を簡単な実装として作成するので、ここに私がすることを示します:

- (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];
}

もちろん、悪いアラート/確認/プロンプト要求を除外するのはあなた次第です。

13
bendytree

そして、これが 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)
}
12

ここに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: {});
}
2
Hassan Taleb
  1. WKWebviewコンテナーコントローラーにプロトコルを実装します。 WKUIDelegate
  2. WKWebviewに設定を追加して、viewDidLoad() asでJavaScriptを有効にします。

    // enable JS
    webView.configuration.preferences.javaScriptEnabled = true
    
  3. 登録WKWebview UIデリゲートin viewDidLoad() as

    self.webView.uiDelegate = self
    
  4. クラスに以下のデリゲートを実装します。

    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)
    }
    
0