Search code examples
javascriptiosmonitorwkwebviewnsurlprotocol

How can i monitor requests on WKWebview?


How can i monitor requests on WKWebview?

I'v tried using NSURLprotocol (canInitWithRequest) but it won't monitor ajax requests (XHR), only navigation requests(document requests)


Solution

  • Finally I solved it

    Since I don't have control over the web view content, I injected to the WKWebview a java script that include a jQuery AJAX request listener.

    When the listener catches a request it sends the native app the request body in the method:

    webkit.messageHandlers.callbackHandler.postMessage(data);
    

    The native app catches the message in a delegate called:

    (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
    

    and perform the corresponding actions

    here is the relevant code:

    ajaxHandler.js -

    //Every time an Ajax call is being invoked the listener will recognize it and  will call the native app with the request details
    
    $( document ).ajaxSend(function( event, request, settings )  {
        callNativeApp (settings.data);
    });
    
    function callNativeApp (data) {
        try {
            webkit.messageHandlers.callbackHandler.postMessage(data);
        }
        catch(err) {
            console.log('The native context does not exist yet');
        }
    }
    

    My ViewController delegate are:

    @interface BrowserViewController : UIViewController <UIWebViewDelegate, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler, UIWebViewDelegate>
    

    And in my viewDidLoad(), I'm creating a WKWebView:

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc]init];
    [self addUserScriptToUserContentController:configuration.userContentController];
    appWebView = [[WKWebView alloc]initWithFrame:self.view.frame configuration:configuration];
    appWebView.UIDelegate = self;
    appWebView.navigationDelegate = self;
    [appWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString: @"http://#############"]]];                                                     
    

    Here is the addUserScriptToUserContentController:

    - (void) addUserScriptToUserContentController:(WKUserContentController *) userContentController{
        NSString *jsHandler = [NSString stringWithContentsOfURL:[[NSBundle mainBundle]URLForResource:@"ajaxHandler" withExtension:@"js"] encoding:NSUTF8StringEncoding error:NULL];
        WKUserScript *ajaxHandler = [[WKUserScript alloc]initWithSource:jsHandler injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
        [userContentController addScriptMessageHandler:self name:@"callbackHandler"];
        [userContentController addUserScript:ajaxHandler];
    }