cancel a SynchronousRequest in iPhone SDK. (TIMEOUT Interval not working)
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.
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.
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
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.
精彩评论