weixin_33725807 2015-02-01 19:54 采纳率: 0%
浏览 37

等待iOS的AJAX

I have a basic HTML page that is nothing more than a starting point for an external script (It only contains a single html, head, script tag). In this external script, I make an AJAX request to a Google API and then do some parsing with the returned data. When I'm done parsing, I put the modified JSON back out onto the DOM and the script terminates.

Everything works out fine on this end. The AJAX request to the Google API goes smoothly and in less than 3 seconds I have an HTML page with some JSON put into a pre tag.

The problems start coming up when I attempt to make a request to this page from an iOS app. The problem is that no matter what I do, the data from the request always comes back with just the basic HTML page. The request is finished before the JSON can be put into the DOM because the AJAX request takes time.

I have tried all of the following methods from within the app to no avail.

  1. Straight up +[NSData dataWithContentsOfURL:options:error:]
  2. NSHTTPRequest
  3. [NSURLConnection sendSynchronousRequest:returningResponse:error:]
  4. NSURLRequest

I have used every different way to make a request from an iOS app but they all have the same problem. Every time the request is made to my page, only the basic HTML page is returned. Here is a sample output from all 4 of these methods.

<html>
    <head>
        <!-- Link to our custom script. Makes an AJAX request then puts JSON into the pre -->
        <script src="mpservice.js"></script>
    </head>

    <pre id="output"></pre>

</html> 

Notice how the pre tag is empty because at the time of the request's termination, the AJAX call and parsing has not yet finished and I have not yet put the JSON into the DOM.

My question is as follows, How can I make a request from within an iOS app that will wait for any AJAX calls to finish before returning?

Thank you for your time and if I have not been specific enough, feel free to leave a comment. If you wish to view the page that I am talking about (for proof that JSON is eventually getting put into the pre tag, go to silicode.us/freeform.

  • 写回答

1条回答 默认 最新

  • weixin_33736649 2015-02-01 21:39
    关注

    Simple mistake here. What you're assuming is happening, as I understand it, is that the page will load (and render) when you make calls to [NSData dataWithContentsOfURL:options:error:] etc. - This is not the case. These requests that you've listed only retrieve the HTML in a single request, they do no loading of extra assets (like images or CSS) and they do no JavaScript processing. They simply make a HTTP request for a file (the webpage), which is returned unmodified and not rendered.

    If you have data that is presented on the page using Javascript, your only option is to run that Javascript. The only way you can run that JavaScript (that's good-practice) is to render that page in a UIWebView.

    You could make the UIWebView in iOS like so:

    UIWebView *browser = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    NSURL *websiteUrl = [NSURL URLWithString:@"http://silicode.us/freeform/"];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:websiteUrl];
    [browser loadRequest:urlRequest];
    

    At this stage, the webpage will render in the browser and eventually present the JSON in the pre-tag. You could probably wait in a loop to check if it appears:

    - (void)checkPreTag {
        NSString *preContent = [browser stringByEvaluatingJavaScriptFromString:@"function f() { var op = document.getElementById(\"output\"); return op.innerHTML.trim(); } f();"];
        if ([preContent length] > 0) {
            // do something with the data
        } else {
            // wait again
            [self performSelector:@selector(checkPreTag) withObject:nil afterDelay:0.25];
        }
    }
    

    I haven't tested this code, but I'm sure only minor modifications should be needed (if at all) to make it fit your use-case.

    Just be aware that this method is far from ideal, and you should seek a more direct route to the JSON content rather then waiting for it to be asynchronously prepared.

    You should also only start checking the checkPreTag function after the page has loaded, using the delegate method: - (void)webViewDidFinishLoad:(UIWebView *)webView

    评论

报告相同问题?

悬赏问题

  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上