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

发布于 2024-09-26 00:47:23 字数 981 浏览 1 评论 0 原文

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

我使用以下命令创建了一个 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 秒! 感谢你的帮助,这很荒谬

I've queried this forum for hours looking for an idea/answer/solution for my problem, but came up empty every time.

i have created a SynchronousRequest using the following:

    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];

the connection is established, and the data is retrieved successfully to aData.
but, when there is a connection problem, or the server is not available, the request is attempting to connect for 75 seconds which is tooooo much time for the timeout interval,
i have added the setTimeoutInterval parameter (with 3 seconds) but it does not affect the connection,

i saw some answers from people saying that i should use NSTimer, and runLoop,
but it's not clear to me how this should be implemented.

PLEASE HELP!

the users are waiting 75 seconds before they get a timeout error message! it's ridiculous

appreciate your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤独患者 2024-10-03 00:47:23

在 iPhone 上,最小超时间隔被硬编码到框架中,您无法将超时设置为低于 75 秒。苹果这样做是因为在处理蜂窝数据连接时经常会出现严重的延迟。

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

阅读 Apple 关于如何设置异步连接的说明,这是一个很好的开始。

如果你确实想设置一个非常短的超时,你可以像这样使用 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 请求,因为同步请求会阻止运行循环,并且在请求完成之前计时器不会触发。

On the iPhone a minimum timeout interval is hard-coded into the framework, you can't set the timeout below 75 seconds. Apple did this because there's frequently a significant amount of lag when you're dealing with cellular data connections.

What you want to do in most situations use an asynchronous network connection (so that your GUI doesn't freeze) and allow the request to go the full 75 seconds before timing out.

Read Apple's instructions for how to set up an asynchronous connection, it's a great start.

If you really do want to set a very short timeout, you can use an NSTimer like this:

- (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]
}

I'm not at my desktop, so that code may be buggy and it's definitely incomplete. Also note that you can't easily use a timer to kill a synchronous web requset, since the synchronous request blocks the runloop and the timer won't fire until the request is done.

雨落□心尘 2024-10-03 00:47:23

我可以建议查看 简单 URL 连接
从该代码中,发送 NSMutableURLRequest 用于

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

检索和发送数据(但请查看代码的其余部分)。也许问题出在 sendSynchronousRequest 上,您可以避免使用它吗?

问候

may I suggest having a look at the sample code from simpleURLconnections?
From that code, the NSMutableURLRequest is sent using

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

for both retrieving and sending data (but have a look at the rest of the code). Maybe the problem lies in the sendSynchronousRequest and you can avoid using that ?

Regards

葵雨 2024-10-03 00:47:23

您可以使用如下代码(取自我正在开发的应用程序) - 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 类和委托方法。

You could use some code like the following (taken from an app I'm working on) - isFinished is a global variable:

- (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;
}

Probably not the cleanest solution, but it works. BTW this code is making use of the WordPress XMLRPCConnection class and delegate methods, but the same if possible with the NSURLConnection class and delegate methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文