2

我的 iOS 应用程序使用 php 脚本向数据库发出请求,并发送回一些数据。数据库命中非常简单,只是根据唯一键获取一些数据。

它在 wifi 上运行良好(延迟不到一秒),但在 3g 上运行缓慢到无法使用的地步。谁能告诉我可能是什么原因,或者我可以在哪里探索更多?我想像 facebook 或 googlemaps 这样的应用程序比我正在做的数据密集得多,但它们的响应速度似乎要快得多。我可能向服务器发送不超过 20-30 个字符(加上 JSON 添加的任何开销),并返回 ~500-1000 个字符(加上 JSON 添加的任何开销)。

我正在同步发送东西,但我认为异步不会对我有帮助......数据不会出现,直到我收到消息。

我的发送和接收代码是:

+ (id)queryDBJSON:(NSString*)script inputs:(id)post
{
    NSError *error;
    NSData *jsonPayload = [NSJSONSerialization dataWithJSONObject:post options:NSJSONWritingPrettyPrinted error:&error];

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", script]];

    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
    [theRequest setHTTPMethod:@"POST"];
    [theRequest setHTTPBody:jsonPayload];

    NSHTTPURLResponse* urlResponse = nil;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&urlResponse error:&error];
    if ([urlResponse statusCode] != 200)
    {
        return nil;
    }

    NSString *strResult = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    NSData *jsonData = [strResult dataUsingEncoding:NSUTF8StringEncoding];

    id aa = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
    return aa;
}

感谢您的任何投入!

4

1 回答 1

1

这些情况下的问题不是网络带宽,而是网络延迟(一个小请求仍然需要很长时间)。不幸的是,您无法解决网络延迟问题。因此,有几点观察:

  1. As rmaddy says, you simply must do your network operations asynchronously (either with synchronous calls in a background queue or using asynchronous methods). If you don't and your app fails to respond in a timely manner, not only will you suffer a UX with unacceptable delays, but if it takes long enough, iOS may even kill your app. If you don't want iOS killing your app when there is a high network latency, you must use asynchronous network operations.

  2. Beyond the obvious (and necessary) solution of doing asynchronous network operations, you generally cache previous result sets (so rather than just showing the user a UIProgressView and stopping all interaction with your app until the asynchronous calls are done, you can show the user the last good results). If you look at apps like Facebook (or, really, any well executed app that interacts with the network), you'll see that they show you what you saw when you last visited that page, they give you some visual indication that further network operations are in progress (e.g. at the very least, the spinning network activity indicator in the status bar), and as new results come in over the network, they then update the view accordingly.

  3. A more sophisticated approach is to initiate the asynchronous network requests that the user will need for subsequent operations as soon as the app starts (rather than waiting until the user navigates to the screen for which that network data is needed). This only works in those cases where the user is navigating to different parts of your app that need to make different network requests, but it's a wonderful way to isolate the user from the network latency in those cases.

  4. If you absolutely can't cache previous result sets for a Facebook-like UX, then still do your network operations asynchronously, but present the user with UI that makes it clear that network operations are in progress (e.g. a UIProgressView with perhaps on a black UIView with a 50% alpha that covers the rest of the screen). That gives the user a visual indication that your app can't present results until the network operation is done. And because you're doing the operations asynchronously, iOS won't kill your app.

于 2013-04-01T17:44:35.327 回答