2010-10-05 4 views
1

J'ai interrogé ce forum pendant des heures à la recherche d'une idée/réponse/solution pour mon problème, mais est apparu vide à chaque fois.annulez une requête synchrone dans le SDK iPhone. (Intervalle TIMEOUT ne fonctionne pas)

i ai créé un SynchronousRequest en utilisant ce qui suit:

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

la connexion est établie, et les données sont récupérées avec succès à aLes. mais, en cas de problème de connexion, ou si le serveur n'est pas disponible, la requête tente de se connecter pour 75 secondes trop longtemps pour l'intervalle de délai, J'ai ajouté le paramètre setTimeoutInterval (avec 3 secondes)

J'ai vu quelques réponses de gens disant que je devrais utiliser NSTimer, et runLoop, mais je ne vois pas comment cela devrait être implémenté.

S'IL VOUS PLAÎT AIDE!

les utilisateurs attendent 75 secondes avant d'avoir reçu un message d'erreur de temporisation! c'est ridicule

apprécie votre aide.

Répondre

4

Sur l'iPhone, un intervalle de délai minimum est codé en dur dans le cadre, vous ne pouvez pas définir le délai d'attente en dessous de 75 secondes. Apple l'a fait parce qu'il y a souvent beaucoup de retard quand il s'agit de connexions de données cellulaires. Ce que vous voulez faire dans la plupart des situations situations utilisent une connexion réseau asynchrone (de sorte que votre interface graphique ne gèle pas) et permettent à la demande de passer les 75 secondes entières avant l'expiration du délai.

Lire Apple's instructions pour savoir comment configurer une connexion asynchrone, c'est un bon début.

Si vous voulez vraiment définir un délai très court, vous pouvez utiliser un NSTimer comme ceci:

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

Je ne suis pas à mon bureau, de sorte que le code peut être buggy et il est certainement incomplète.Notez également que vous ne pouvez pas facilement utiliser une minuterie pour supprimer un requset web synchrone, car la requête synchrone bloque le cycle et le minuteur ne se déclenche pas tant que la requête n'est pas terminée.

+0

Merci pour cela, je vais vérifier et vous faire savoir –

+1

+1: belle réponse sweet-nuts. – Alan

1

puis-je suggérer de jeter un oeil à l'exemple de code de simpleURLconnections? A partir de ce code, le NSMutableURLRequest est envoyé à l'aide

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

pour les récupérer et envoyer des données (mais un coup d'oeil au reste du code). Peut-être que le problème réside dans le sendSynchronousRequest et vous pouvez éviter d'utiliser cela?

Cordialement

+0

Oui, le problème est avec 'sendSynchronousRequest:'. Si vous l'exécutez sur le thread principal, l'intégralité de votre application se bloque jusqu'à ce que la réponse soit terminée ou que la requête ait échoué. Cela signifie que la boucle d'exécution principale est bloquée, donc pas de temporisation ou de réponse aux événements. – JeremyP

+0

C'est exactement ce que je veux, thread principal - Demande synchrone, –

+0

par conséquent, connectionWithRequest ne va pas aider, car il va effectuer une requête Synchronous. –

0

Vous pouvez utiliser un code comme le suivant (pris à partir d'une application que je suis en train) - isFinished est une variable globale:

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

Probablement pas la solution la plus propre, mais travaux. BTW ce code utilise la classe WordPress XMLRPCConnection et les méthodes de délégation, mais la même chose si possible avec la classe NSURLConnection et les méthodes déléguées.

+0

Hey, je vois que vous utilisez les méthodes de délégation de connexion, (didReceiveResponse ...) donc cela signifie que vous travaillez asynchrone et non synchrone, cela fonctionnera-t-il avec sendaSynchronousRequest? –

+0

Y a-t-il une raison spécifique pour laquelle vous préféreriez utiliser les méthodes synchrones par rapport aux méthodes asynchrones dans votre situation? –

Questions connexes