2014-11-12 6 views
34

Sto riscontrando qualche problema nel trovare una WKWebView in iOS 8 per visualizzare una finestra di avviso chiamata da Javascript. Dopo aver creato un WKWebView standard e caricato un file HTML, ho un pulsante sulla pagina che crea un semplice avviso con del testo. Funziona in UIWebView e in Google Chrome/Safari, ma non sembra funzionare in WKWebView. Qualsiasi aiuto è apprezzato.iOS WKWebView non mostra la finestra di avviso javascript()

La mia configurazione è la seguente:

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

L'HTML ha la seguente funzione:

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

e un pulsante:

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

Questa configurazione funziona in UIWebView e regolare browser, ma non funziona in WKWebView. Mi manca qualcosa nella configurazione? Dovrei usare uno dei delegati WK per controllare il comportamento di avviso/conferma? Grazie.

+1

sto affrontando lo stesso problema. Inoltre, non riesco a collegare l'ispettore safari al mio ipad in modo da non visualizzare avvisi o console.log. Questo rende lo sviluppo sulla wkwebview praticamente un inferno sulla terra. – ruipacheco

+0

puoi provare ad ospitare il file html e provare "http: //" invece di "file: //", potrebbe essere a causa di questo bug in wkwebview: http://www.openradar.me/radar?id=5839348817723392 – krisrak

+0

I file html sono archiviati localmente in modo che possano essere accessibili offline. Il file viene caricato senza problemi, è solo la finestra di avviso che non viene visualizzata quando si tocca il pulsante. – Charlie

risposta

46

Per risolvere questo è necessario un WKUIDelegate per la visualizzazione Web. È compito del delegato decidere se deve essere visualizzato un avviso e in che modo. È necessario implementarlo per avvisare, confermare e inserire il testo (prompt).

Ecco il codice di esempio, senza alcuna convalida delle caratteristiche pagina url o di sicurezza:

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

Più nel Official Documentation

+0

Sembra che questo fosse il problema. Grazie! – Charlie

+3

Se ancora non si richiama questa funzione delegato, ricordare di provare gli altri due: 'runJavaScriptConfirmPanelWithMessage' e' runJavaScriptTextInputPanelWithPrompt'. L'evento dipende dal tipo di avviso. –

+4

C'è un ottimo standard per l'implementazione di tutti e 3 i metodi delegati qui: https://gist.github.com/davbeck/8613f2e74e8fc335c14d –

8

Proprio per espandere un po ', WKWebView richiede di mostrare avvisi, istruzioni visualizzate, e conferma te stesso A tale scopo, diventando un WKUIDelegate:

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

quindi assegnare il delegato:

web.UIDelegate = self; 

allora avete bisogno di applicare concretamente allerta, pronta, e confermare. Creo WKWebViewPanelManager.h/m come un facile implementazione, ecco quello che faccio:

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

Naturalmente, spetta a voi per filtrare i cattivi/conferma/le domande messaggio di avviso.

11

Ed ecco che nel

func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, 
    initiatedByFrame frame: WKFrameInfo, completionHandler:() -> Void) { 

    let alertController = UIAlertController(title: message, message: nil, 
     preferredStyle: UIAlertControllerStyle.Alert); 

    alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel) { 
     _ in completionHandler()} 
    ); 

    self.presentViewController(alertController, animated: true, completion: {}); 
} 
21

Swift 3 con tutte e 3 le funzioni opzionali:

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

dove questo codice deve essere inserito? Lo inserisco direttamente nel 'class ViewController' - si compila, ma il mio JS non è in grado di attivare' prompt() ' – godblessstrawberry

+0

@godblessstrawberry Dovrebbe essere inserito nel tuo wiDelegate (WKUIDelegate) del WKView, tipicamente un controller di visualizzazione che implementa quel protocollo. – Lio