2014-05-05 9 views
10

I-Daten am Abrufen iOS7 der neuen URL-Anforderung Methoden, etwa so:Wie Sie eine Block basierte URL Anfrage erneut zu versuchen

NSMutableURLRequest *request = [NSMutableURLRequest 
    requestWithURL:[NSURL URLWithString:[self.baseUrl 
    stringByAppendingString:path]]]; 

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; 
    NSUInteger responseStatusCode = [httpResponse statusCode]; 

    if (responseStatusCode != 200) { 
     // RETRY (??????) 
    } else  
     completionBlock(results[@"result"][symbol]); 
}]; 
[dataTask resume]; 

Leider von Zeit zu Zeit erhalte ich HTTP-Antworten, die den Server nicht erreichbar ist (response code != 200) und müssen dieselbe Anfrage erneut an den Server senden.

Wie kann das gemacht werden? Wie würde ich mein Code-Snippet oben ausfüllen müssen, wo mein Kommentar // RETRY ist?

In meinem Beispiel rufe ich den Completion-Block nach einem erfolgreichen Abruf. Aber wie kann ich die gleiche Anfrage noch einmal senden?

Vielen Dank!

+0

Lohnt es sich, die meisten Statuscodes erneut versuchen? Es scheint, als wäre der einzige Status-Code, den es wert ist, erneut zu versuchen, 500. Ich bin brandneu, also bin ich neugierig darauf, einen Verbindungsfehler oder einen Serverfehler erneut zu versuchen. –

Antwort

12

Ihre Anfrage Code in einer Methode setzen und es wieder in einem dispatch_async Block nennen;)

- (void)requestMethod { 

    NSMutableURLRequest *request = [NSMutableURLRequest 
            requestWithURL:[NSURL URLWithString:[self.baseUrl 
                     stringByAppendingString:path]]]; 

    __weak typeof (self) weakSelf = self; 
    NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; 
     NSUInteger responseStatusCode = [httpResponse statusCode]; 

     if (responseStatusCode != 200) { 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^{ 
       [weakSelf requestMethod]; 
      }); 
     } else  
      completionBlock(results[@"result"][symbol]); 
    }]; 
    [dataTask resume]; 

} 
+0

Ähnliche Fragen. Was, wenn dies eine Klassenmethode sein muss und einige Parameter an sie übergeben werden müssen? –

+1

Ist eine separate Warteschlange erforderlich? '[weakSelf selectorName]' wird richtig machen? Wenn ein oberer Schwellenwert für einen Wiederholungsversuch vorhanden ist, werden Endlosschleifen verhindert, falls der Server ausgefallen ist. – GoodSp33d

+0

Um Endlosschleife zu vermeiden, können Sie einfach eine Zählervariable verwenden. Für die Warteschlange können Sie sie in eine beliebige Warteschlange stellen, indem Sie dispatch_async verwenden, damit die Funktion sofort zurückkehrt. –

13

Es ist besser, einen Wiederholungszähler, um Ihre Methode läuft für immer zu verhindern:

- (void)someMethodWithRetryCounter:(int) retryCounter 
{ 
    if (retryCounter == 0) { 
     return; 
    } 
    retryCounter--; 

    NSMutableURLRequest *request = [NSMutableURLRequest 
            requestWithURL:[NSURL URLWithString:[self.baseUrl 
                     stringByAppendingString:path]]]; 

    __weak __typeof(self)weakSelf = self; 

    NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; 
     NSUInteger responseStatusCode = [httpResponse statusCode]; 

     if (responseStatusCode != 200) { 
      [weakSelf someMethodWithRetryCounter: retryCounter]; 
     } else 
      completionBlock(results[@"result"][symbol]); 
    }]; 
    [dataTask resume]; 
} 

Es sollte folgenden Weg genannt werden:

[self someMethodWithRetryCounter:5]; 
+0

der Wiederholungsversuch sollte exponentiell zurück sein + Jitter – hariszaman

+0

@Avt: In diesem Fall, wenn Web-Service fehlschlägt, nachdem Retrycounter abläuft, wird diese Methode Fehlerinfo IMO nicht zurückgegeben, die es sollte. –

+1

@ i.AsifNoor In einem Abschlussblock sollte ein Fehler zurückgegeben werden. In der Frage hat der Completion Block 'completionBlock' jedoch nur einen Parameter. Um meine Idee klar zu machen, habe ich mich entschieden, meinen Code nicht so originalgetreu wie möglich zu machen. – Avt

Verwandte Themen