Best Practices zum Erstellen einer Warteschlange von NSURLSessionTasks
Was sind die besten Methoden für die Herstellung einer seriellen queue von NSURLSessionTasks
?
In meinem Fall brauche ich:
- Holen Sie sich eine URL innerhalb eines JSON-Datei (
NSURLSessionDataTask
) - Die Datei herunterladen, URL (
NSURLSessionDownloadTask
)
Hier ist, was ich habe, so weit:
session = [NSURLSession sharedSession];
//Download the JSON:
NSURLRequest *dataRequest = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *task =
[session dataTaskWithRequest:dataRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
//Figure out the URL of the file I want to download:
NSJSONSerialization *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSURL *downloadURL = [NSURL urlWithString:[json objectForKey:@"download_url"]];
NSURLSessionDownloadTask *fileDownloadTask =
[session downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:playlistURL]]
completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
NSLog(@"completed!");
}];
[fileDownloadTask resume];
}
];
Abgesehen von der Tatsache, dass das schreiben einer Abschluss-block in einen anderen Abschluss sieht chaotisch, ich bin immer ein EXC_BAD_ACCESS Fehlermeldung, wenn ich call [fileDownloadTask resume]
... obwohl fileDownloadTask
ist nicht null!
Also, was ist der beste Weg, Sequenzierung NSURLSessionTasks
?
Kommentar zu dem Problem
Für die Sequenzierung, wie etwa eine NSOperationQueue?
InformationsquelleAutor der Frage Eric | 2013-12-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie verwenden diese Vorgehensweise, die die meisten straight forward: https://stackoverflow.com/a/31386206/2308258
Oder verwenden Sie eine operation queue und machen Sie die Aufgaben, abhängig vom jeweils anderen
=======================================================================
Über die HTTPMaximumConnectionsPerHost Methode
HTTPMaximumConnectionsPerHost nur dafür sorgen, dass man gemeinsamen Verbindung verwendet werden, für die Aufgaben der session, aber es bedeutet nicht, dass Sie werden Seriell verarbeitet.
Können Sie überprüfen, ob auf der Netzwerk-Ebene mit http://www.charlesproxy.com/, Sie wil entdecken, dass, wenn die Einstellung HTTPMaximumConnectionsPerHost, Ihre Aufgaben noch gestartet werden zusammen in der gleichen Zeit, indem Sie NSURLSession und nicht Seriell wie man glaubt.
Expriment 1:
Mit task2: "url" = download.thinkbroadband.com/20MB.zip
Ergebnis: task1 completionBlock heißt dann task2 completionBlock heißt
Abschluss Blöcke genannt werden könnte, in der Reihenfolge, die Sie erwarten im Falle der Aufgaben nehmen die gleiche Menge an Zeit jedoch, wenn Sie versuchen, laden Sie zwei verschiedene Dinge mit dem gleichen NSURLSession werden Sie entdecken, dass NSURLSession nicht über eine zugrunde liegende Bestellung Ihrer Anrufe, aber nur komplettiert, was zuerst fertig ist.
Expriment 2:
task2: "url" = download.thinkbroadband.com/10MB.zip (kleinere Datei)
Ergebnis: task2 completionBlock heißt dann task1 completionBlock heißt
Abschließend müssen Sie die Bestellung selbst, NSURLSession keine Logik zur Bestellung Anfragen, wird es nur nennen die completionBlock, was zuerst fertig ist, auch wenn die Einstellung der maximalen Anzahl von verbindungen pro host auf 1
PS: Sorry für das format der post, ich habe nicht genug Ruf zu posten screenshots.
InformationsquelleAutor der Antwort taiyungo
Edit:
Als mataejoon hat darauf hingewiesen, Einstellung
HTTPMaximumConnectionsPerHost
1 wird nicht garantieren, dass die verbindungen Seriell verarbeitet. Einen anderen Ansatz probieren (wie in meiner ursprünglichen Antwort unten), wenn Sie brauchen eine zuverlässige serielle WarteschlangeNSURLSessionTask
.Einen einfachen Weg zur Umsetzung einer first-in-first-out serielle Warteschlange
NSURLSessionTasks
ist die Ausführung aller Aufgaben auf einNSURLSession
hat seineHTTPMaximumConnectionsPerHost
- Eigenschaft auf1
:dann Aufgaben hinzufügen, um es in der Reihenfolge, die Sie wollen.
InformationsquelleAutor der Antwort Eric
Benutze ich NSOperationQueue (als Owen vorgeschlagen hat). Setzen Sie die NSURLSessionTasks in NSOperation-Unterklassen und stellen Abhängigkeiten. Abhängige tasks warten, bis der Aufgabe, die Sie abhängig sind, abgeschlossen sind, bevor es läuft, aber wird nicht überprüfen Sie den status (Erfolg oder Fehler), so fügen Sie einige Logik, um den Prozess zu Steuern.
In meinem Fall, die erste Aufgabe prüft, ob der Benutzer über ein gültiges Konto und erstellt, wenn nötig. In der ersten Aufgabe, die ich aktualisieren NSUserDefault Wert, um anzuzeigen, das Konto gültig ist (oder es ist ein Fehler). Die zweite Aufgabe überprüft das NSUserDefault Wert und wenn alles OK verwendet die Anmeldeinformationen des Benutzers zu veröffentlichen einige Daten an den server.
(Kleben der NSURLSessionTasks in separaten NSOperation Unterklassen auch meinen code leichter zu navigieren)
Fügen Sie die NSOperation Unterklassen der NSOperationQueue und stellen Abhängigkeiten:
In der ersten NSOperation Unterklasse überprüft, ob Konto existiert auf dem server:
In der nächsten NSOperation post-Daten:
InformationsquelleAutor der Antwort greentor
und Einsatz, wie dies
InformationsquelleAutor der Antwort Peter Lapisu