2010-10-04 14 views
2

J'ai un service REST qui utilise un auth_token qui expire chaque souvent. lorsqu'une requête échoue, je veux réauthentifier (que je suis capable de faire ) puis renverrons la même TTURLRequest exacte dans le suivant de façon générique:trois20 TTURLRequest renvoyer

- (void)request:(TTURLRequest*)request didFailLoadWithError: 
(NSError*)error { 
     NSLog(@"error %@ %@ %@", [error localizedDescription], [error 
localizedFailureReason], [error localizedRecoverySuggestion] 
       ); 


     if (numRetries == 0) { 
       [self authenticateUser:nil]; 

       request.urlPath = [request.urlPath 
stringByReplacingOccurrencesOfRegex:@"access_token=([\\w-]+)" 
withString:[NSString stringWithFormat:@"access_token=%@", 
accessToken]]; 

       NSLog(@"URL: %@", request.urlPath); 
       [request send]; 

       numRetries++; 

     } 

} 

tous mes TTURLRequest s utilisent la même délégué qui utilise cette méthode d'échec. mais pour une raison quelconque, quand j'appelle [request send] la requête arrive à la phase de "chargement", mais ne semble jamais se terminer. Toutefois, si je fais un rafraîchissement manuel (en faisant glisser la vue de la table) re-génère le TTURLRequest à partir de zéro et semble fonctionner correctement.

Quelle est la bonne façon de «renvoyer» cette demande?

Répondre

0

Je suis récemment tombé sur le même problème. Je n'ai pas suffisamment exploré Three20 pour savoir si le fait de réessayer des demandes échouées est prévu, mais j'ai trouvé le problème et une solution fiable (et simple).

Après que [demande d'envoi] est appelée la deuxième fois, l'instance de TTURLRequest est désallouée avant la fin du chargement. Si vous observez TTURLRequestModel.m dans Three20Network, vous pouvez voir que la dernière requête du modèle (_loadingRequest) est libérée avant que la nouvelle requête ne soit conservée. Si la dernière demande se trouve être le même que la nouvelle demande (comme dans votre cas), il est de conserver le nombre passe à 0 et il se dealloc'd:

///////////////////////////////////////////////////////////////////////////// 
- (void)requestDidStartLoad:(TTURLRequest*)request { 
    [_loadingRequest release]; 
    _loadingRequest = [request retain]; 
    [self didStartLoad]; 
} 

Je résolu ce problème en sous-classement et TTURLRequestModel.m remplaçant cette méthode par ce qui suit:

///////////////////////////////////////////////////////////////////////////////// 
- (void)requestDidStartLoad:(TTURLRequest*)request { 
    [request retain]; 
    [_loadingRequest release]; 
    _loadingRequest = request; 
    [self didStartLoad]; 
} 

Ceci a fonctionné dans mes tests et ne semble pas affecter négativement quoi que ce soit.

Remarque: Si vous utilisez TTURLJSONResponse pour l'objet de réponse de votre demande, vous devrez allouer une nouvelle instance et la définir pour request.response avant d'envoyer à nouveau send. Si vous regardez TTURLJSONResponse.m dans extThree20JSON, vous verrez que la méthode processResponse affirme (nil == _rootObject). Cela échouera si l'instance de réponse a déjà été utilisée dans une demande.