отменить синхронный запрос в iPhone SDK. (TIMEOUT Interval не работает) - PullRequest
1 голос
/ 05 октября 2010

Я часами опрашивал этот форум в поисках идеи / ответа / решения для моей проблемы, но каждый раз появлялся пустым.

Я создал SynchronousRequest, используя следующее:

    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];

соединение установлено, и данные успешно извлекаются в aData. но когда возникает проблема с подключением или сервер недоступен, запрос пытается подключиться в течение 75 секунд , что слишком много для интервала времени ожидания, я добавил параметр setTimeoutInterval (с 3 секундами), но он не влияет на соединение,

я видел ответы от людей, которые говорили, что я должен использовать NSTimer и runLoop, но мне не ясно, как это должно быть реализовано.

ПОЖАЛУЙСТА, ПОМОГИТЕ!

пользователи ждут 75 секунд, прежде чем они получат сообщение об ошибке тайм-аута! это смешно

ценю вашу помощь.

Ответы [ 3 ]

4 голосов
/ 05 октября 2010

На iPhone минимальный интервал тайм-аута жестко запрограммирован в каркас, вы не можете установить тайм-аут ниже 75 секунд.Apple сделала это потому, что при работе с сотовыми сетевыми соединениями часто наблюдается значительная задержка.

Что вы хотите сделать в большинстве ситуаций, использовать асинхронное сетевое соединение (так что вашGUI не останавливается) и позволяет запросу завершиться за 75 секунд до истечения времени ожидания.

Прочитайте Инструкции Apple о том, как установить асинхронное соединение, это отличное начало.

Если вы действительно хотите установить очень короткий тайм-аут, вы можете использовать NSTimer, например:

- (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]
}

Я не на рабочем столе, поэтому код может содержать ошибкии это определенно неполноТакже обратите внимание, что вы не можете легко использовать таймер для уничтожения синхронного веб-реквизита, так как синхронный запрос блокирует цикл выполнения, и таймер не сработает, пока запрос не будет выполнен.

1 голос
/ 05 октября 2010

Могу ли я предложить взглянуть на пример кода из simpleURLconnections ? Из этого кода NSMutableURLRequest отправляется с использованием

 self.connection = [NSURLConnection connectionWithRequest:request delegate:self];

как для получения, так и для отправки данных (но посмотрите на остальную часть кода). Может быть, проблема в sendSynchronousRequest, и вы можете избежать этого?

Привет

0 голосов
/ 05 октября 2010

Вы можете использовать некоторый код, подобный следующему (взятый из приложения, над которым я работаю) - isFinished является глобальной переменной:

- (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;
}

Вероятно, не самое чистое решение, но оно работает.Кстати, этот код использует класс WordPress XMLRPCConnection и методы делегата, но, если возможно, то же самое с классом NSURLConnection и методами делегата.

...