비동기 모드에서 NSURLConnection을 사용하고 완료를 기다리고 있습니다. 대기 중에 NSRUNLOOP을 사용하여 이벤트를 처리합니다. 대부분의 경우 (3G 및 WIFI) 에서 작동하지만 GSM DATA 및 EDGE 환경에서는 응용 프로그램이 임의로 끊깁니다.IPHONE SDK : NSURLConnection 비동기/대기 완료 버그?
내 코드 :
(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;
}
확인을 구현하지만 난 완료를 기다려야합니다. 시간 초과도 처리해야합니다. – mneveren
UI를 차단하려면 요청을 시작할 때'UIAlerView'를 표시하고'connectionDidFinishLoading'에서이를 닫으십시오. – FelixLam