NSURLConnection не отвечает - PullRequest
       26

NSURLConnection не отвечает

3 голосов
/ 20 февраля 2012

Я пытаюсь получить некоторые данные из URL, но по какой-то причине ничего не происходит, когда я делаю следующее. Не достигаются ни didReceiveResponse:, didReceiveData:, didFailWithError:, ни connectionDidFinishLoading:, кроме случаев, когда я добавляю тайм-аут в свой запрос, выполняя это: [request setTimeoutInterval:10.0]

Вот что я делаю:

-(void)getConfigFromServer{
    [self getContentAtURL:kUrlGetUser];
}

//Va chercher le contenu à l'URL passée en paramètre
- (void)getContentAtURL: (NSURL *)url {

    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSString * userLogin = [userDefaults objectForKey:@"UserLogin"];
    NSString * userPassword = [userDefaults objectForKey:@"UserPassword"];
    NSURL * urlFinal = [NSURL URLWithString:[NSString stringWithFormat:@"%@", url]];
    NSLog(@"Request : %@", [NSString stringWithFormat:@"%@", url]);
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:urlFinal];  
    [request setHTTPShouldHandleCookies:NO];
    [request setTimeoutInterval:10.0];

    NSString *sourceString = [NSString stringWithFormat:@"%@:%@", userLogin, userPassword]; 
    NSData * sourceData = [sourceString dataUsingEncoding:NSUTF8StringEncoding];  
    NSString *authString = [sourceData base64EncodedString];  

    authString = [NSString stringWithFormat: @"Basic %@", authString];
    [request setValue:authString forHTTPHeaderField:@"Authorization"];
    [request setValue:@"text/xml" forHTTPHeaderField:@"Accept"];
    NSURLConnection * connection=[NSURLConnection connectionWithRequest:request delegate:self];

    if(connection){
        NSLog(@"Connection started");
        receivedData = [NSMutableData data];
    }else{
        NSLog(@"Error while trying to initiate the connection");
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [receivedData setLength:0];
    if ([response respondsToSelector:@selector(statusCode)])
    {
        int statusCode = [((NSHTTPURLResponse *)response) statusCode];
        if (statusCode >= 400)
        {
            [connection cancel];  // stop connecting; no more delegate messages
            NSDictionary *errorInfo
                = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:
                NSLocalizedString(@"Server returned status code %d",@""),
                statusCode]
                    forKey:NSLocalizedDescriptionKey];
            NSError *statusError = [NSError errorWithDomain:@"Error"
                code:statusCode
                userInfo:errorInfo];
            [self connection:connection didFailWithError:statusError];
        }
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [receivedData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    NSLog(@"Connection failed! Error - %@ %@",[error localizedDescription],[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self fetchedData:receivedData];
}

РЕДАКТИРОВАТЬ: У меня все еще есть эта проблема, и теперь она есть на реальном устройстве тоже. Как я уже сказал в комментариях, я впервые использую ARC в этом приложении и использую XCode 4.2.

Есть идеи?

Ответы [ 5 ]

5 голосов
/ 26 августа 2013

Это старая ветка, но все же этот ответ может кому-то помочь.

Если вы вызываете это в фоновом потоке, проверьте, завершается ли ваш поток до вызова делегатов.

Попробуйте сделать это.

NSURLConnection * connection = [[NSURLConnection alloc] 
                                initWithRequest:request
                                       delegate:self startImmediately:NO];

[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] 
                      forMode:NSDefaultRunLoopMode];
[connection start];
0 голосов
/ 20 февраля 2012

Некоторые мысли здесь:

  1. Пожалуйста, не не храните пароли в UserDefaults, используйте для этого связку ключей (возможно, вы только тестируете, я просто хотел, чтобы это было упомянуто)
  2. Почему вы конвертируете свой NSURL URL-адрес в новый NSURL, позвонив по номеру stringWithFormat:?(О, я вижу, @ade уже упоминал об этом)
  3. Это приложение, поддерживающее ARC ?Если нет, ваш NSMutableData будет автоматически освобожден слишком быстро, используйте self.receivedData = [NSMutableData data], и вы увидите сбой.
  4. Попробуйте сделать вашу NSURLConnection переменной экземпляра и удерживайте ее.Я думаю, что это должно сработать так, как вы делаете это прямо сейчас, но я склонен держаться за это и никогда не сталкивался с проблемой, о которой вы упомянули здесь.это сработало и обнаружил, что на iPhone тайм-аут не может быть меньше 240 секунд .Да, меня это тоже смутило, но: https://stackoverflow.com/a/3611383/148335
0 голосов
/ 20 февраля 2012

Я думаю, что проблема будет со стороны сервера.Попробуйте увеличить TimeoutInterval до 60, чтобы было больше времени для получения данных с сервера.Разве вы не получили сообщение об истечении времени ожидания соединения через 10 секунд?

РЕДАКТИРОВАТЬ

Привет, я думаю, что вы все еще не нашли решение.Когда я прочитал код подробно, я обнаружил, что некоторые утверждения сбивают с толку.

1) [request setValue:@"text/xml" forHTTPHeaderField:@"Accept"]; заменить на

    [request setValue:@"text/plain" forHTTPHeaderField:@"Accept"];

Также включите,

    [request setValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];

Инаконец ...

Ошибка «тайм-аут соединения» означает, что iPhone не получает данные с сервера.Как только iPhone получит данные, он позвонит - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data.Попробуйте поставить NSLog после каждого оператора, чтобы убедиться, что переменные содержат желаемое значение.Попробуйте проверить длину данных - sourceData - перед отправкой ...

0 голосов
/ 20 февраля 2012

Сообщение об ошибке, как вы сказали в комментариях, говорит о том, что время запроса истекло.Я уверен, что если вы удалите строку с тайм-аутом, вы получите либо тот же ответ или фактические данные, через 60 секунд.Убедитесь, что вы подождали достаточно, потому что если ваше соединение по какой-то причине очень слабое, запрос может не завершиться через 60 секунд, поскольку он продолжает загружать данные.

Находится ли ваше приложение на переднем плане, пока вы запускаете это?Убедитесь, что вы не приостановили его.

Кроме того, вы говорите, что сервер подключен к сети, но ваш код истекает.Означает, что, возможно, что-то не так с вашим соединением.

В другом комментарии вы говорите, что иногда это работает.Еще больше указывает на то, что соединение слабое / ненадежное или разрывается.

0 голосов
/ 20 февраля 2012

Вы передаете NSURL в свой getContentAtURL, но затем обрабатываете его, как если бы это была строка в:

NSURL * urlFinal = [NSURL URLWithString:[NSString stringWithFormat:@"%@", url]];

попробуйте изменить его на:

NSURL * urlFinal = [NSURL URLWithString:[NSString stringWithFormat:@"%@", [url absoluteString]]];

Кстати, вы знаете, что вы не используете свой логин и пароль, не так ли?

EDIT:

Когда вы говорите, что ReceiveData = [NSMutableData data]; что такое данные?

Я думаю, что это может быть проблемой.

Я склонен использовать следующее для настройки объекта данных при первом поступлении данных:

- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData {
    if (receivedData ==nil) { receivedData = [[NSMutableData alloc] initWithCapacity:2048]; } 
    [receivedData appendData:incrementalData];
}
...