web-dev-qa-db-ja.com

プログラムでwkwebviewのコンソールログを読み取る方法

プログラムでWkWebviewに読み込まれているwebappのコンソールログを読み取ろうとしています。

これまでのところ、私の研究では不可能です。

どうすればこれを達成できますか?

19
NaveenKumar

JavaScriptのconsole.log()のデフォルト実装を再評価(オーバーライド)して、代わりにwindow.webkit.messageHandlers.postMessage(msg)を使用してメッセージを転送することができます。次に、ネイティブコードでWKScriptMessageHandler :: didReceiveScriptMessageを使用してjavascript postMessage(msg)呼び出しをインターセプトし、ログに記録されたメッセージを取得します。

ステップ1)postMessage()を使用するためにconsole.logのデフォルト実装を再評価します

// 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

ステップ2)WKScriptMessageHandler :: didReceiveScriptMessageでネイティブコードのjavascript postMessageをインターセプトする

- (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

MacのSafariブラウザをWKWebViewに接続して、コンソールにアクセスすることができます。

Safariから[開発]タブを開き、iOSシミュレーターがWKWebViewを開いた状態で実行しているときに、クリックしてコンソールを開きます。見る:

enter image description here

2
Oded Regev

通常、コンソールのログはjsで次のように定義されます

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

私の答えは handling-javascript-events-in-wkwebview

WKWebViewを構成で初期化する

    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)

または、KVOを使用してプロパティ「estimatedProgress」を監視し、JavaScriptを評価してjsを挿入します

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

メッセージを受信するWKScriptMessageHandlerプロトコルを実装します。

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

Swift 4.2および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

これは私のために働きました(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")

次に、プロトコルWKScriptMessageHandlerに準拠して、リダイレクトされたコンソールメッセージを次のように取得します。

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