web-dev-qa-db-fra.com

NSMutableURLRequest timeout interval non pris en considération pour POST requêtes

J'ai le problème suivant. Sur un NSMutableURLRequest utilisant la méthode HTTPPOST l'intervalle de temporisation défini pour la connexion est ignoré. Si la connexion Internet a un problème (mauvais proxy, mauvais DNS), la demande d'URL échoue après environ 2 à 4 minutes mais pas avec NSLocalizedDescription = "timed out";

NSUnderlyingError = Error Domain=kCFErrorDomainCFNetwork Code=-1001 UserInfo=0x139580 "The request timed out.

Si la méthode http utilisée est GET, cela fonctionne très bien. La connexion est async sur https.

    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    

    [request setTimeoutInterval:10];

    //Set the request method to post
    [request setHTTPMethod:@"POST"];

    if (body != nil) {
        [request setHTTPBody:body];
    }

    // Add general parameters to the request
    if (authorization){
        [request addValue: authorization forHTTPHeaderField:@"Authorization"];
    }
    [request addValue: WS_Host forHTTPHeaderField:@"Host"];
    [request addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];

    [[NSURLCache sharedURLCache] setDiskCapacity:0];

    [self addToQueueRequest:request withDelegate:delegate];

'
32
user177844

Selon un article publié sur le forum des développeurs Apple Apple, l'intervalle de temporisation minimum pour POST est de 240 secondes. Tout intervalle de temporisation plus court que celui-ci est ignoré).

Si vous avez besoin d'un délai d'expiration plus court, utilisez une demande asynchrone avec une minuterie et appelez annuler sur NSURLConnection si nécessaire.

lien vers le fil: ici

28
user214852

iOS 6 a résolu ce problème.

NSMutableURLRequest *request = [NSMutableURLRequest 
                                requestWithURL:[NSURL URLWithString:url] 
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20];

[request setHTTPMethod:method];
[request setHTTPBody:requestBody];
NSLog(@"%f", [request timeoutInterval]); 
//20.0 in iOS 6
//240.0 in iOS 4.3, 5.0, 5.1
27
freestyler

Correction de la suggestion de Clay Chambers: avec un minuteur personnalisé Ajout d'un minuteur dans une sous-classe de NSURLConnection

if (needsSeparateTimeout){

    SEL sel = @selector(customCancel);

    NSMethodSignature* sig = [self methodSignatureForSelector:sel];

    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:sig];

    [invocation setTarget:self];

    [invocation setSelector:sel];

    NSTimer *timer = [NSTimer timerWithTimeInterval:WS_REQUEST_TIMEOUT_INTERVAL invocation:invocation repeats:NO];

    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

}

Dans la méthode d'annulation personnalisée, la connexion est annulée

[super cancel];     
10
user177844

Il semble que le problème décrit ici soit toujours confronté à iOS 7.1 (ou réapparu). Heureusement, il semble que la propriété timeoutIntervalForResource de la configuration sur le NSURLSession puisse résoudre ce problème.

[~ # ~] modifier [~ # ~]

Selon les observations de @XiOS, cela fonctionne pour des délais d'attente inférieurs à (environ) 2 minutes.

3
Julian Król

Si vous voulez savoir comment gérer l'erreur de dépassement de délai, je pense que personne n'a encore répondu à cette question

Permettez-moi d'écrire pice de mon code pour expliquer ce point

// replace "arg" with your argument you want send to your site 
 NSString * param = [NSString stringWithFormat:@"arg"];

    NSData *Postdata = [param dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[Postdata length]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
// replace "yoursite" with url of site you want post to 
    [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"http//yoursite"]]];
// set what ever time you want in seconds 120 mean 2 min , 240 mean 4 min 
    [request setTimeoutInterval:120];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded"  forHTTPHeaderField:@"Current-Type"];

    [request setHTTPBody:Postdata];
    NSURLConnection * connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];

// if request time out without response from server error will occurred 

-(void) connection:(NSURLConnection * ) connection didFailWithError:(NSError *)error {    
    if (error.code == NSURLErrorTimedOut) 
        // handle error as you want 
        NSLog(@"Request time out , Please try again later");
}

J'espère que cette aide avec quelqu'un vous demandera comment gérer l'erreur de dépassement de délai

0
Mina Fawzy