取消iPhone SDK中的SynchronousRequest。 (TIMEOUT间隔不起作用)

时间:2010-10-05 14:01:05

标签: iphone objective-c post timeout nsurlconnection

我已经查询了这个论坛几个小时,为我的问题寻找一个想法/答案/解决方案,但每次都空了。

我使用以下方法创建了一个SynchronousRequest:

    NSMutableURLRequest *theRequest = [[NSMutableURLRequest alloc] initWithURL:url];
    NSString *msgLength = [NSString stringWithFormat:@"%d", [params length]];
    [theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
    [theRequest setHTTPMethod:@"POST"];
    [theRequest setTimeoutInterval:3.0];
    [theRequest setCachePolicy:NSURLRequestReturnCacheDataElseLoad];
    [theRequest setHTTPBody: [params dataUsingEncoding:NSUTF8StringEncoding]];
    NSData  *aData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];

建立连接,并成功检索数据到aData。 但是,当出现连接问题或服务器不可用时,请求正在尝试连接 75秒,这对于超时间隔来说太长时间了, 我添加了setTimeoutInterval参数(3秒),但不影响连接,

我看到人们说我应该使用NSTimer和runLoop的一些答案, 但我不清楚这应该如何实施。

请帮助!

用户在收到超时错误消息之前等待75秒!这太荒谬了

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

在iPhone上,最小超时间隔被硬编码到框架中,您无法将超时设置为低于75秒。 Apple之所以这样做,是因为当您处理蜂窝数据连接时经常出现大量延迟。

大多数情况下你想要做的事情是使用异步网络连接(这样你的GUI不会冻结)并允许请求在超时前整整75秒。

阅读Apple's instructions了解如何设置异步连接,这是一个很好的开始。

如果你真的想设置一个非常短的超时,你可以使用这样的NSTimer

- (void)loadURL:(NSURL *)url {
    /* Set up the NSURLConnection here */

    [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(cancelURLConnection:) userInfo:nil repeats:NO];
}

- (void)cancelURLConnection:(NSTimer)timer {
    [self.connection cancel]
}

我不在我的桌面上,所以代码可能有问题,而且肯定是不完整的。另请注意,您无法轻松使用计时器来终止同步Web请求,因为同步请求会阻止runloop,并且在请求完成之前计时器不会触发。

答案 1 :(得分:1)

我可以建议您查看simpleURLconnections的示例代码吗? 从该代码中,使用

发送NSMutableURLRequest
 self.connection = [NSURLConnection connectionWithRequest:request delegate:self];

用于检索和发送数据(但查看其余代码)。也许问题在于sendSynchronousRequest,你可以避免使用它吗?

此致

答案 2 :(得分:0)

您可以使用以下代码(取自我正在处理的应用程序) - isFinished是一个全局变量:

- (void)someMethod {
    [[WSXMLRPCController sharedInstance] validateLicenseWithServiceURL:serviceUrl username:username password:password delegate:self];

    isFinished = NO;
    NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow:10]; // break the loop after 10 seconds and not finished with the request from the call above ...
    while(!isFinished && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:endDate]){
        if([endDate compare:[NSDate date]] == NSOrderedAscending){
            [self connection:nil didFailWithError:nil forMethod:nil];
        }
    }       
}


- (void)connection: (XMLRPCConnection *)connection didFailWithError: (NSError *)error forMethod: (NSString *)method {
   isFinished = YES;
}

- (void)connection: (XMLRPCConnection *)connection didReceiveResponse: (XMLRPCResponse *)response forMethod: (NSString *)method {   
   isFinished = YES;
}

可能不是最干净的解决方案,但它确实有效。顺便说一句,这段代码正在使用WordPress XMLRPCConnection类和委托方法,但如果可能的话,使用NSURLConnection类和委托方法也是如此。