web-dev-qa-db-fra.com

Comment lire les journaux de la console de wkwebview par programmation

J'essaie de lire les journaux de la console de la webapp qui est chargée par programme dans mon WkWebview.

jusqu'à présent dans mes recherches ce n'est pas possible.

Comment puis-je atteindre cet objectif?

19
NaveenKumar

Vous pouvez réévaluer (remplacer) l'implémentation par défaut de Javascript console.log () pour utiliser window.webkit.messageHandlers.postMessage (msg) pour transmettre le message à la place. Et puis intercepter l'appel javascript postMessage (msg) au code natif à l'aide de WKScriptMessageHandler :: didReceiveScriptMessage pour obtenir le message enregistré.

Étape 1) Réévaluez l'implémentation par défaut de console.log pour utiliser postMessage ()

// javascript to override console.log to use messageHandlers.postmessage
NSString * js = @"var console = { log: function(msg){window.webkit.messageHandlers.logging.postMessage(msg) };";
// evaluate js to wkwebview
[self.webView evaluateJavaScript:js

Étape 2) Intercepter le postMessage javascript dans le code natif à WKScriptMessageHandler :: didReceiveScriptMessage

- (void)viewDidLoad
{
    // create message handler named "logging"
    WKUserContentController *ucc = [[WKUserContentController alloc] init];
    [ucc addScriptMessageHandler:self name:@"logging"];
    // assign usercontentcontroller to configuration    
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    [configuration setUserContentController:ucc];
    // assign configuration to wkwebview    
    self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) configuration:configuration];
}


- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    // what ever were logged with console.log() in wkwebview arrives here in message.body property
    NSLog(@"log: %@", message.body);
}
3
noxo

Il est possible de connecter le navigateur Safari de votre Mac à WKWebView et d'accéder à la console.

Depuis Safari, ouvrez l'onglet "Développer" et pendant que le simulateur iOS fonctionne avec WKWebView ouvert - cliquez simplement dessus pour ouvrir la console. Voir:

enter image description here

2
Oded Regev

Normalement, la journalisation de la console est définie dans js comme

    "window.addEventListener("message",function(e){console.log(e.data)});"

Ma réponse a été adaptée de handling-javascript-events-in-wkwebview !

Initialiser WKWebView avec la configuration

    let config = WKWebViewConfiguration()
    let source = "document.addEventListener('message', function(e){
     window.webkit.messageHandlers.iosListener.postMessage(e.data); })"
    let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
    config.userContentController.addUserScript(script)
    config.userContentController.add(self, name: "iosListener")
    webView = WKWebView(frame: UIScreen.main.bounds, configuration: config)

Ou utilisez KVO observez la propriété "estimationProgress" et injectez js en évaluant JavaScript

    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
    {
        if ([keyPath isEqualToString:@"estimatedProgress"])
        {
            CGFloat progress = [change[NSKeyValueChangeNewKey] floatValue];
            if (progress>= 0.9)
            {
                NSString *jsCmd = @"window.addEventListener(\"message\",function(e){window.webkit.messageHandlers.iosListener.postMessage(e.data)});";
        //@"document.addEventListener('click', function(e){ window.webkit.messageHandlers.iosListener.postMessage('Customize click'); })";

                [_webView evaluateJavaScript:jsCmd completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
                    NSLog(@"error:%@",error);
                }];
            }
        }
    }

implémentez le protocole WKScriptMessageHandler pour recevoir le message:

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) 
    {
            print("message: \(message.body)")
            // and whatever other actions you want to take
    }
2
jeffreysuej

Swift 4.2 et 5

 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
      webView.evaluateJavaScript("your javascript string") { (value, error) in
          if let errorMessage = (error! as NSError).userInfo["WKJavaScriptExceptionMessage"] as? String {
                print(errorMessage)
          }
      }
 }
0
Barath

Cela a fonctionné pour moi (Swift 4.2/5):

// inject JS to capture console.log output and send to iOS
let source = "function captureLog(msg) { window.webkit.messageHandlers.logHandler.postMessage(msg); } window.console.log = captureLog;"
let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
webView.configuration.userContentController.addUserScript(script)
// register the bridge script that listens for the output
webView.configuration.userContentController.add(self, name: "logHandler")

Ensuite, conformément au protocole WKScriptMessageHandler, récupérez les messages de console redirigés avec les éléments suivants:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    if message.name == "logHandler" {
        print("LOG: \(message.body)")  
    }
}
0
Richard West-Soley