2

我正在尝试在异步模式下使用 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;

}

4

2 回答 2

3

NSURLConnection 已经是异步的。只需实现委托方法。如果您想更新 MainThread 上的 UI(例如进度条),您可以在didReceiveData.

于 2010-02-12T09:47:15.257 回答
0

我使用NSNotification或那个目的。在 DidFinishLoading 方法中发布通知,

[[NSNotificationCenter defaultCenter] postNotificationName:@"Name" object:someObject];

并通过以下方式在任何类中处理此通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMethod:) notificationName:@"Name" object:nil];

并实施

-(void)handleMethod:(NSNotification *)ntf
于 2010-02-12T20:31:03.253 回答