简体   繁体   中英

Trigger webViewDidFinishLoad for google search results

I am trying to run code when a page is finished loading in my webViewDidFinishLoad . However, if I visit google.com in my UIWebView then type in a search, the first query works, but all additional searches will not trigger the webViewDidFinishLoad . According to other articles this is because of google using ajax requests. To combat this inject javascript into the pages to trigger an iOS method once done loading. However, it doesn't seem to work properly for google, but works for other ajax sites like yahoo.

Am I doing the javascript properly? Does anyone have a suggestion on how to get the javascript to call the Obj-C method after the ajax is done loading?

ajax_handler.js (bundled with app)

var s_ajaxListener = new Object();
var originalReadyStateChange;
s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
s_ajaxListener.callback = function () {
    console.log(this);
    if (this.readyState == 4) {
        console.log("TRIGGERING HANDLER");
        window.location='x3AjaxHandler://' + this.url;
        console.log(originalReadyStateChange);

    } else {
        console.log("READY STATE NOT FINISHED");
    }
    originalReadyStateChange();
};

XMLHttpRequest.prototype.open = function(a,b) {
    if (!a) var a='';
    if (!b) var b='';
    s_ajaxListener.tempOpen.apply(this, arguments);
    s_ajaxListener.method = a;
    s_ajaxListener.url = b;
    if (a.toLowerCase() == 'get') {
        s_ajaxListener.data = b.split('?');
        s_ajaxListener.data = s_ajaxListener.data[1];
    }
}

XMLHttpRequest.prototype.send = function(a,b) {
    if (!a) var a='';
    if (!b) var b='';
    s_ajaxListener.tempSend.apply(this, arguments);
    if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;

    console.log(this);
    originalReadyStateChange = this.onreadystatechange;
    this.onreadystatechange = s_ajaxListener.callback;
}

WebView

#define CocoaJSHandler          @"x3AjaxHandler"

static NSString *ajaxInjectionHandler;

+(void)initialize
{
    ajaxInjectionHandler = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ajax_handler" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"js: %@", ajaxInjectionHandler);
}

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"SHOULD LOAD");

    if ([[[request URL] scheme] caseInsensitiveCompare:CocoaJSHandler] == NSOrderedSame) {
        NSString *requestedURLString = [[[request URL] absoluteString] substringFromIndex:[CocoaJSHandler length] + 3];

        NSLog(@"ajax request: %@", requestedURLString);
        [self webViewDidFinishLoad:webView];
        return NO;
    }
    return YES;
}

- (void)webViewDidStartLoad:(UIWebView *)webView {

    NSLog(@"INJECTING");
    [webView stringByEvaluatingJavaScriptFromString:ajaxInjectionHandler];
}

You could try to create and remove an iFrame with the url schema and path as src attribute. Setting window.location didn't worked for me. This worked for me so far:

function sendRequestToiOS(url) {
    // Create and append an iFrame to the document and set it with the url schema
    var iframe = document.createElement("IFRAME");
    iframe.setAttribute("src", "x3AjaxHandler://" + url);
    // For some reason we need to set a non-empty size for the iOS6 simulator...
    iframe.setAttribute("height", "1px");
    iframe.setAttribute("width", "1px");
    document.documentElement.appendChild(iframe);
    iframe.parentNode.removeChild(iframe);
    iframe = null;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM