Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Interesting question. </p> <p>There are two parts to make this work: a JavaScript handler and UIWebView delegate methods. In JavaScript, we can modify prototype methods to trigger events when an AJAX request is created. With our UIWebView delegate, we can capture these events.</p> <p><strong>JavaScript Handler</strong></p> <p>We need to be notified when an AJAX request is made. I found the solution <a href="https://stackoverflow.com/questions/3596583/javascript-detect-an-ajax-event">here</a>.</p> <p>In our case, to make the code work, I put the following JavaScript in a resource called <strong>ajax_handler.js</strong> which is bundled with my app.</p> <pre><code>var s_ajaxListener = new Object(); s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open; s_ajaxListener.tempSend = XMLHttpRequest.prototype.send; s_ajaxListener.callback = function () { window.location='mpAjaxHandler://' + this.url; }; 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; s_ajaxListener.callback(); } </code></pre> <p>What this will actually do is change the location of the browser to some made up URL scheme (in this case, <strong>mpAjaxHandle</strong>) with info about the request made. Don't worry, our delegate with catch this and the location won't change.</p> <p><strong>UIWebView Delegate</strong></p> <p>First, we need to read our JavaScript file. I suggest doing storing it in a static variable. I'm in the habit of using +initialize.</p> <pre><code>static NSString *JSHandler; + (void)initialize { JSHandler = [[NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ajax_handler" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil] retain]; } </code></pre> <p>Next, we want to inject this JavaScript before a page is done loading so we can receive all events.</p> <pre><code>- (void)webViewDidStartLoad:(UIWebView *)webView { [webView stringByEvaluatingJavaScriptFromString:JSHandler]; } </code></pre> <p>Finally, we want to capture the event. </p> <p>Since the URL Scheme is made up, we don't want to actually follow it. We return <strong>NO</strong> and all is well.</p> <pre><code>#define CocoaJSHandler @"mpAjaxHandler" - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if ([[[request URL] scheme] isEqual:CocoaJSHandler]) { NSString *requestedURLString = [[[request URL] absoluteString] substringFromIndex:[CocoaJSHandler length] + 3]; NSLog(@"ajax request: %@", requestedURLString); return NO; } return YES; } </code></pre> <p>I created a sample project with the solution but have nowhere to host it. You can message me if you can host it and I'll edit this post accordingly.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload