2015-07-15 13 views
11

Ich erstelle eine NSMutableRequest:NSURLSessionDataTask Timeout nachfolgende Anfragen andernfalls

self.req = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0]; 

Der Timeout eingestellt ist 10 Sekunden zu sein, weil ich der Benutzer nicht will, zu lange warten, um ein Feedback zu bekommen. Danach erstelle ich ein NSURLSessionDataTask:

NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response; 
    if (error) { 
     // this is where I get the timeout 
    } 
    else if (httpResp.statusCode < 200 || httpResp.statusCode >= 300) { 
     // handling error and giving feedback 
    } 
    else { 
     NSError *serializationError = nil; 
     NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&serializationError]; 
    } 
    [task resume]; 
} 

Das Problem ist der Server geht in Gateway-Timeout und es braucht viel Zeit. Ich bekomme den Timeout-Fehler und ich gebe dem Benutzer eine Rückmeldung, aber alle folgenden API-Aufrufe scheitern auf Grund eines Timeout-Fehlers auf die gleiche Weise. Der einzige Weg, um es zu stoppen, ist die App zu töten und neu zu beginnen. Gibt es etwas, was ich tun sollte, um die Aufgabe oder die Verbindung nach einem Timeout-Fehler zu beenden? Wenn ich kein Timeout einstelle und ich warte bis ich den Fehlercode vom Server bekomme funktionieren alle folgenden Anrufe einwandfrei (aber der User wartet sehr!).

Ich habe versucht, um die Aufgabe abzubrechen:

NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response; 
    if (error) { 
     // this is where I get the timeout 
     [task cancel]; 
    } 
    ... 
    [task resume]; 
} 
+0

Ich denke, könnten Sie benötigen die 'self.req' neu zu initialisieren, wenn ein Fehler/timeout ist. Bin mir aber nicht sicher. – Mrunal

+0

versuchen Sie, die Verbindungen mit der POSTMAN App in Chrome aufzurufen, und sehen Sie, ob Sie immer noch den Timeout-Fehler erhalten oder nicht –

+0

Erstellen Sie diese Aufgabe in einem Block? Oder ein anderer Thread als der Haupt-Thread? –

Antwort

4

ich nicht Sie die Aufgabe, die Sie begann sehen wieder aufzunehmen. Sie müssen deklarieren:

[task resume]; 

Diese Zeile setzt die Aufgabe fort, wenn sie unterbrochen ist.

Versuchen Sie, die NSURLSession rufen Sie wie folgt vor:

[NSURLSession sharedSessison] instead of self.session 

und ungültig machen die Sitzung mit:

[[NSURLSession sharedSession]invalidateAndCancel]; 

Von Apple Dokumentation:

Wenn Ihre App nicht mehr benötigt eine Sitzung , annulliere es durch Aufrufen von invalidateAndCancel (um ausstehende Aufgaben abzubrechen) oder finishTasksAndInvalidate (um zuzulassen ausstehende Aufgaben, die abgeschlossen werden müssen, bevor das Objekt ungültig gemacht wird).

- (void)invalidateAndCancel 

Einmal für ungültig erklärt, Verweise auf die Delegierten und Callback-Objekte sind gebrochen. Sitzungsobjekte können nicht wiederverwendet werden.

Damit ausstehende Aufgaben bis zum Abschluss ausgeführt werden, rufen Sie stattdessen finishTasksAndInvalidate auf.

- (void)finishTasksAndInvalidate 

Diese Methode liefert sofort ohne Aufgaben zu warten zu beenden. Sobald eine Sitzung ungültig wird, können neue Aufgaben nicht in der Sitzung erstellt werden, aber vorhandene Aufgaben werden bis zum Abschluss fortgesetzt. Nachdem der letzte Task abgeschlossen ist und die Sitzung den letzten Delegataufruf ausführt, sind Verweise auf die Delegat- und Callback-Objekte unterbrochen. Sitzungsobjekte können nicht wiederverwendet werden.

Um alle ausstehenden Aufgaben abzubrechen, rufen Sie stattdessen invalidateAndCancel auf.

+0

Ja, ich habe den Lebenslauf hier in der Frage vergessen. Ich werde es bearbeiten. Und die einzige Methode, die ich auffordern kann, die Aufgabe zu annullieren, ist "Abbrechen". Ich kann die anderen nicht sehen. Ich habe es versucht, aber es löst das Problem nicht. Danke –

+0

wie r rufst du den cancel? –

+0

Ich habe die Frage bearbeitet. Danke –

0

Der wahrscheinlichste Grund für ein Timeout ist entweder, dass DNS in eine IP-Adresse aufgelöst wurde, die nicht existiert, oder dass der Server abgestürzt ist und neu gestartet werden muss. In jedem Fall, wenn eine Anfrage mit Zeitüberschreitung fehlschlägt, ist es wahrscheinlich, dass mehr Anfragen mit Zeitüberschreitung ebenfalls fehlschlagen.

Sie müssen Ihre Anwendung natürlich so schreiben, dass sie überleben kann, wenn ihre Server nicht antworten.

+0

Wenn ich das Timeout auf 60 statt 10 Sekunden setze, bekomme ich die "Gateway Timeout" vom Server und alle Anfragen, die ich danach mache, funktionieren perfekt. Das Problem liegt vor, wenn das Zeitlimit vor der Antwort vom Server auftritt. Alle folgenden Anfragen schlagen fehl, bis ich die App beendet habe. –

1

Sie können Timeout auf unterschiedliche Weise eingestellt wie Code folgenden

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
sessionConfiguration.timeoutIntervalForRequest = timeout; 
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:nil delegateQueue:nil]; 
1

Das Problem, das Sie am meisten wahrscheinlich hier zu begegnen, ist, dass Sie Ihre Aufgabe ist nicht annullieren oder abgeschlossen und somit hält die Sitzung noch mehr Aufgaben zu akzeptieren . Gemäß der Dokumentation von Apple

Nachdem Sie eine Aufgabe erstellt haben, starten Sie sie, indem Sie ihre Wiederaufnahme-Methode aufrufen. Die Sitzung behält dann einen starken Verweis auf die Aufgabe bei, bis die Anforderung beendet oder fehlgeschlagen ist.

Als T_77 vorgeschlagen, versuchen Sie es mit [NSURLSession sharedSession]

Auch eine weitere Sache, die ich versuchen würde, zu diesem Zeitpunkt versucht zu tun, um herauszufinden, ob es einen Zyklus zwischen dem Sitzungsobjekt erstellt behalten ist und die Aufgabe, unter Verwendung der Instrumente

Eine weitere Sache, die passieren könnte, ist, dass die Anfrage nicht richtig gebildet wird und nicht ausgeführt wird oder hängt. Ich hatte ein ähnliches Problem, als ich versuchte, eine URL in eine Webansicht zu laden. Die Seite wurde nicht geladen und gab keinen Fehler aus. Versuchen Sie, die URL-Anfrage auch einmal zu überprüfen.

Danke, Suraj

Verwandte Themen