2

A backend API I need to connect to takes about 3-4 minutes to return a response. The iOS client seems to timeout at exactly 60 seconds (which is the default), and I can't figure out how to extend that time out.

I have tried to set the timeoutInterval for the NSURLRequest to a large number, and set the Connection: Keep-Alive header, but I have no luck. Here is the code I am using, omitting some API details:

NSURL *url = [NSURL URLWithString:@"myAPI"];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setHTTPMethod:@"POST"];

NSString *postString = @"key1=val1&key2=val2...";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

request.timeoutInterval = 600.0f;

[request setValue:@"Keep-Alive" forHTTPHeaderField:@"Connection"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
     NSLog(@"data = %@", data);
}];

No data is returned and all response header fields are empty, even though the backend API is still processing the request.

I heard I might need to set something called a "socketTimout" interval so the socket knows to keep the connection open longer, but I do not know where to set that.

4

3 回答 3

6

与其尝试延长超时时间,不如稍微修改一下服务器架构。让服务器在获得所有数据后立即返回 200 OK,然后在后台队列中完成处理。创建另一个可用于检索数据的 API 调用,并让 iOS 应用程序定期检查数据是否已被处理。或者,使用推送通知让用户/电话知道数据何时完成处理。

如果您碰巧使用的是 Ruby on Rails,那么将长时间运行的进程设置为在工作线程上发生是非常容易的。看一下delayed_job Ruby gem。

如果由于某种原因您无法修改服务器的运行方式,请尝试确保您使用的 API 本身没有设置超时。我想不出 iOS 会忽略您设置的 timeoutInterval 的原因,除非该属性是只读的。尝试改用这个 init 方法:

- initWithURL:cachePolicy:timeoutInterval:
于 2013-05-09T20:47:51.323 回答
1

您是否尝试过使用 NSURLConnection 委托方法而不是 NSURLConnection 委托方法sendAsynchronousRequest

通过使用:

NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];

您可以监视委托方法didReceiveData并将传入数据附加到 NSMutableData 的实例:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.data appendData:data];
}

这样,至少你会知道你正在接收数据,你甚至可以向你的用户展示一个进度条或其他东西。

于 2013-05-09T20:31:54.560 回答
0

埃里克,检查这篇文章的答案:

NSURLConnection 超时?

本质上你使用这个方法NSURLRequest

requestWithURL:cachePolicy:timeoutInterval:

于 2013-05-09T20:45:54.163 回答