我试图在异步模式下使用NSURLConnection并等待完成。 在等待期间,我使用NSRUNLOOP来处理事件。它适用于大多数情况下(3G和WIFI) 但应用程序在GSM DATA和EDGE环境中随机挂断。
我的代码:
(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
_requestCompleted = TRUE;
CFRunLoopStop(CFRunLoopGetCurrent());
}
(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
_response = (NSHTTPURLResponse *)response;
[ _response retain];
}
(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
/* Append the new data to the received data. */
[_receivedData appendData:data];
}
(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
_requestError = error;
NSLog(@"request error - cause : %@", [_requestError localizedDescription ]);
_requestCompleted = TRUE;
[_requestError retain];
CFRunLoopStop(CFRunLoopGetCurrent());
}
(NSString*)downloadFileFromURL:(NSString*)url
{
NSURLRequest *request = nil;
NSString *contents = nil;
NSData *response = nil;
int tries;
NSURLConnection *URLConnection = nil;
int i = 0;
NSDate* dateLimit;
[_mutex lock];
NSLog(@"url = %@", url);
NSString *requestWithEscaping = [ url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding ];
request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestWithEscaping]
cachePolicy: NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:30];
for (tries = 0; tries < HTTP_REQUESTS_TRIES && response == nil ; tries ++) {
[_receivedData setLength:0];
_requestCompleted = FALSE;
_requestError = nil;
_requestTimeout = FALSE;
if (URLConnection == nil)
URLConnection = [ NSURLConnection connectionWithRequest:request delegate:self];
else {
[URLConnection cancel ];
[URLConnection start];
}
if (URLConnection == nil) {
NSLog(@"No connection ! maybe mistake in Request Format ?");
continue;
}
for (i = 0; ; i++) {
dateLimit = [[NSDate date] addTimeInterval:INTERVALL_LOOP];
[ [NSRunLoop currentRunLoop] runUntilDate:dateLimit];
if (_requestCompleted == TRUE)
break;
if (i > (int)(HTTP_TIMEOUT_FIRE * (1 / INTERVALL_LOOP))) {
_requestTimeout = TRUE;
break;
}
}
if (_requestTimeout) {
[ URLConnection cancel];
NSLog(@"request timeout");
continue;
}
if (_requestError) {
NSLog(@"request error");
continue;
}
NSLog(@"Request success");
break;
}
if (_requestTimeout) {
_lastErrorType = ServicesRequestManager_error_Network;
[ _lastErrorString setString:@"Délai de connexion depassé"];
[ _mutex unlock];
return nil;
}
if (_requestError) {
NSLog(@"ERROR Cannot get %@ - cause : %@",url, [ _requestError localizedDescription ]);
_lastErrorType = ServicesRequestManager_error_Network;
[_lastErrorString setString:@"Impossible de se connecter" ];
[ _mutex unlock];
return nil;
}
if ([ _response statusCode] != 200 ) {
NSLog(@"ERROR Download file %@ HTTP response - code : %d", url, [ _response statusCode]);
[_lastErrorString setString:[ NSString stringWithFormat:@"Error http code : %d", [_response statusCode]]];
_lastErrorType = ServicesRequestManager_error_Service;
[_lastErrorString setString:@"Le service n'est pas disponible actuellement" ];
[ _mutex unlock];
return nil;
}
contents = [[NSString alloc] initWithData:_receivedData encoding:NSUTF8StringEncoding];
[ _mutex unlock];
return contents;
}
答案 0 :(得分:3)
NSURLConnection已经是异步的。只需实现委托方法。如果您想更新MainThread上的用户界面(例如进度条),您可以在didReceiveData
中执行此操作。
答案 1 :(得分:0)
我使用NSNotification
或那个puspose。在DidFinishLoading方法中发布通知,
[[NSNotificationCenter defaultCenter] postNotificationName:@"Name" object:someObject];
并通过
在任何类中处理此通知[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMethod:) notificationName:@"Name" object:nil];
并实施
-(void)handleMethod:(NSNotification *)ntf