NSURLSession: Wie kann die Zeitüberschreitung für URL-Anfragen erhöht werden?

73

Ich verwende iOS 7 neu NSURLSessionDataTask, um Daten wie folgt abzurufen:

NSURLSession *session = [NSURLSession sharedSession];

NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:
request completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
//
}];

Wie kann ich die Timeout-Werte erhöhen, um den Fehler zu vermeiden "The request timed out"(in NSURLErrorDomainCode = -1001)?

Ich habe die Dokumentation für NSURLSessionConfiguration überprüft , aber keine Möglichkeit gefunden, den Zeitlimitwert festzulegen .

Danke für deine Hilfe!

AlexR
quelle
1
Machst du viele Anfragen? In diesem Fall ist es wahrscheinlich nicht der richtige Ansatz, nur das Zeitlimit zu erhöhen, sondern Sie möchten die Anzahl der gleichzeitigen Anforderungen, die Sie versuchen (z . B. mit NSOperationQueuemit maxConcurrentOperationCount) , einschränken . Dies ist nicht zu kompliziert, wenn Sie die nicht delegierte basierte Wiedergabe von verwenden NSURLSessionund die Abschlussblockwiedergaben verwenden. Aufgrund erheblicher Probleme mit der NSURLSessionArchitektur ist es etwas schwierig, dies richtig zu machen, wenn der delegatenbasierte Ansatz verwendet wird.
Rob
2
Mein Hauptproblem ist, dass der HTTP-Server (der außerhalb meiner Kontrolle liegt) manchmal stark ausgelastet ist und extrem langsam reagiert. Kennen Sie zufällig die Standardwerte für die Zeitüberschreitungen für sharedSession?
AlexR
Nein, aber wie die anderen sagten, sollten Sie einfach Ihre eigenen erstellen defaultSessionConfigurationund die timeOutIntervalForRequestfür Ihren Server geeignete festlegen . Es ist nur so, dass die Zeitüberschreitungsprobleme, die sich aus der Ausgabe von mehr als vier oder fünf gleichzeitigen Anforderungen ergeben, ein völlig anderes Problem sind und eine andere Lösung vorschlagen. Wenn Sie jedoch nur ein oder zwei Anforderungen ausgeben und das Zeitlimit weiterhin überschritten wird, ist das Festlegen der timeoutIntervalEigenschaften der richtige Ansatz.
Rob

Antworten:

124

ObjC

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.timeoutIntervalForRequest = 30.0;
sessionConfig.timeoutIntervalForResource = 60.0;

Schnell

let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = 30.0
sessionConfig.timeoutIntervalForResource = 60.0
let session = URLSession(configuration: sessionConfig)

Was die Dokumente sagen

timeoutIntervalForRequestund timeoutIntervalForResourcegeben Sie das Zeitlimit für die Anforderung sowie die Ressource an.

timeoutIntervalForRequest- Das Zeitlimit, das beim Warten auf zusätzliche Daten verwendet werden soll. Der diesem Wert zugeordnete Timer wird zurückgesetzt, sobald neue Daten eintreffen. Wenn der Anforderungszeitgeber das angegebene Intervall erreicht, ohne neue Daten zu empfangen, wird eine Zeitüberschreitung ausgelöst.

timeoutIntervalForResource- Die maximale Zeit, die eine Ressourcenanforderung in Anspruch nehmen darf. Dieser Wert steuert, wie lange auf die Übertragung einer gesamten Ressource gewartet werden muss, bevor aufgegeben wird. Der Ressourcen-Timer startet, wenn die Anforderung initiiert wird, und zählt, bis entweder die Anforderung abgeschlossen ist oder dieses Zeitlimit erreicht ist, je nachdem, was zuerst eintritt.

Basierend auf der NSURLSessionConfiguration-Klassenreferenz

RaffAl
quelle
7
Hallo Reecon, ich möchte, dass das Timeout-Intervall meiner Webdienste 180 Sekunden (3 Minuten) beträgt. Da ich über NSURLSESSION und dessen timeoutIntervalForRequest und timeoutIntervalForResource gelesen habe, habe ich versucht, diese zu verwenden, was wiederum zu denselben Ergebnissen führte wie timeOutInterval von NSMutableURLRequest.ie. Ich stelle ein Zeitüberschreitungsintervall von 180 Sekunden ein, sessionConfig.timeoutIntervalForRequest = 180.0; sessionConfig.timeoutIntervalForResource = 180.0; aber ich erhalte einen Fehlerrückruf in 75 Sekunden oder in einem zufälligen Zeitintervall mit der Meldung "Die Anforderung ist abgelaufen". Hast du eine Idee dazu?
XiOS
Ich denke, dass durch Apples Doc die Änderung von [NSURLSessionConfiguration defaultSessionConfiguration]nicht wirksam wird [NSURLSession sharedSession]?
xi.lin
7
Beachten Sie, dass der Standardwert für timeoutIntervalForRequest60 Sekunden und der Standardwert für timeoutIntervalForResource7 Tage beträgt.
Adam Johns
5
timeoutIntervalForRequest funktioniert, wenn ein Wert unter 60 festgelegt ist. Wenn ich ihn jedoch auf einen höheren Wert einstelle, tritt eine Zeitüberschreitung nach 60 Sekunden auf ...
Diogo Souza
@XiOS haben Sie eine Lösung für Ihre Lösung gefunden? Ich erhalte auch eine Zeitüberschreitung bei der Anforderung innerhalb von 45 Sekunden, wenn es tatsächlich 60 Sekunden sind.
Shirish
17

Für den Fall, dass Swift-Entwickler hierher kommen

Dazu müssen Sie verwenden

    let urlconfig = NSURLSessionConfiguration.defaultSessionConfiguration()
    urlconfig.timeoutIntervalForRequest = 12
    urlconfig.timeoutIntervalForResource = 12
    self.session = NSURLSession(configuration: urlconfig, delegate: self.delegates, delegateQueue: nil)
Obst A.Suk
quelle
Ich erhalte einen nicht erkannten Selektor, der an einen Instanzfehler für timeoutIntervalForRequest
Marcus
Ich habe für Swift 3 aktualisiert, erhalte aber den Fehler. Klasse hat keine Mitgliedsdelegierten?
Adamprocter
@ sruit-a-suk Ist nicht unveränderlich "veränderbar" und "var" veränderlich. Die Timeout-Anforderung und die Ressourcen werden also nie festgelegt?
Matthew Ferguson
9

In schnellem 3. Timeout 15 Sekunden.

    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = TimeInterval(15)
    configuration.timeoutIntervalForResource = TimeInterval(15)
    let session = URLSession(configuration: configuration)
Danil Shaykhutdinov
quelle
Dies erklärt nicht den Unterschied zwischen timeoutIntervalForRequestund timeoutIntervalForResource .
Martin
4

NSURLSessionConfiguration enthält die Eigenschaft timeoutIntervalForRequest:

@property NSTimeInterval timeoutIntervalForRequest

um das Timeout-Intervall zu steuern. Es gibt auch timeoutIntervalForResource für das Timeout nach dem Initiieren der Anforderung.

Wojtek Surowka
quelle
3

In meinem Fall habe ich das Timeout der falschen Klasse erhöht. Mein Timeout-Fehler wurde behoben, indem das Timeout der URLRequest und nicht der URLSession erhöht wurde

var request = URLRequest(url: url)
request.timeoutInterval = 30
Nico Dioso
quelle
Dies hat das Timeout-Problem für mich gelöst. Ich gehe davon aus, dass dies in Verbindung mit den obigen Einstellungen erforderlich ist.
Arcady Bob
2

In SWIFT 3.0 müssen Sie verwenden

 if let cleanURLString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed),
    let theURL: Foundation.URL = Foundation.URL(string: cleanURLString) {

    var task:URLSessionDataTask?
    let urlconfig = URLSessionConfiguration.default
    urlconfig.timeoutIntervalForRequest = 20
    urlconfig.timeoutIntervalForResource = 60
    let session = Foundation.URLSession(configuration: urlconfig, delegate: self, delegateQueue: OperationQueue.main)

    let request = URLRequest(url: theURL)
    request.httpMethod = "POST"
    request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
    let paramString = YourParameterString
    request.httpBody = paramString.data(using: String.Encoding.utf8)

    task = session.dataTask(with: request) {
        (data, response, error) in
        // Do here
    })
    dataTask.resume()
}
Lineesh K Mohan
quelle
Beachten Sie, dass es auch möglich ist, das Zeitlimit zu ändern, nachdem die Sitzung bereits erstellt wurde: let session = Foundation.URLSession (Konfiguration: ...); session.configuration.timeoutIntervalForRequest = 20. Dies scheint jedoch bei .groundground-Sitzungen nicht auf diese Weise zu funktionieren.
Vitalii
1

Für Swift 4:

let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = TimeInterval(15)
config.timeoutIntervalForResource = TimeInterval(15)
let urlSession = URLSession(configuration: config)

Das timeoutIntervalForRequest gilt für alle Aufgaben in Sitzungen, die auf dieser Konfiguration basieren. Die timeoutIntervalForResource gilt für alle Aufgaben in Sitzungen, die auf dieser Konfiguration basieren.


quelle