6

Ursprünglich dachte ich, dass, wenn ein NSURLSessionDownloadTask erfolgreich beendet URLSession:downloadTask:didFinishDownloadingToURL: Methode aufgerufen wird, wenn es aus irgendeinem Grund fehlschlägt - URLSession:task:didCompleteWithError:. Es funktioniert wie erwartet im Simulator (nur eine dieser Methoden wird für einen Download-Task aufgerufen), aber auf dem Gerät ist dies nicht der Fall: Im Falle eines Fehlers werden beide Methoden aufgerufen, URLSession:downloadTask:didFinishDownloadingToURL: ist die erste. (eine dieser beiden Methoden die gleiche Aufgabe in Parametern übergeben)Handhabung NSURLSessionDownloadTask Fehler

Gibt es etwas, was ich vermisse?

+0

Ich habe das gleiche Verhalten festgestellt, dass DidFinishDownloadingToURL neben DidCompleteWithError aufgerufen wird. Dies hat enorme Probleme für uns verursacht. Wie hast du daran gearbeitet? – RunLoop

+0

Standort könnte in diesem Fall nill sein. Kannst du das überprüfen? – AsifHabib

Antwort

1

Verwenden Abschluss Block statt delegieren:

NSURLSessionDownloadTask *mySessionDownloadTask = [myURLSession downloadTaskWithRequest:myRequest completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if(!error) 
     { 
      // Finish loading 
     } 
     else 
     { 
       // Handle error 
     }); 
}]; 

Hinweis: Wenn Sie nicht über die Hauptwarteschlange erhalten, jede Aktualisierung Benutzeroberfläche verwendet wird verzögert, welches ungeahntes Verhalten verursacht.

+1

Ich möchte, dass meine Benutzer ihre Downloads beendet haben, wenn meine App in den Hintergrundmodus wechselt. Daher kann ich keine Abschlussblöcke anstelle eines Delegaten verwenden (da ich eine Hintergrundsitzung verwende) – dariaa

+0

Ich verstehe. Wie wäre es mit einem globalen BOOL, um zu wissen, ob Sie die Antwort verarbeitet haben? –

+0

Nun, natürlich kann es einen Workaround geben, aber ich wollte etwas tiefer verstehen. Ist es ein erwartetes Verhalten oder ist es ein Fehler, der gemeldet werden sollte usw.Übrigens ist ein 'BOOL'-Flag hier nicht die beste Wahl, da in 'URLSession: downloadTask: didFinishDownloadingToURL:' (welches zuerst aufgerufen wird) die Datei normalerweise in das Dokumentenverzeichnis zur weiteren Verarbeitung kopiert wird. Es wäre schön zu wissen, ob der Download erfolgreich oder mit Fehler beendet wurde. – dariaa

-1

NSURLSessionDownloadTask ist eine Unterklasse von NSURLSessionTask, die eine error Eigenschaft hat. Können Sie das in Ihrer Delegatenmethode URLSession:downloadTask:didFinishDownloadingToURL: überprüfen, bevor Sie versuchen, Ihre Datei zu kopieren?

+0

Die Fehlereigenschaft bleibt null, es sei denn, es handelt sich um einen clientseitigen Fehler. –

1

Laut Apples Dokumentation unter NSURLSessionDownloadDelegate ist es Standardverhalten.

/* Sent when a download task that has completed a download. The delegate should 
* copy or move the file at the given location to a new location as it will be 
* removed when the delegate message returns. URLSession:task:didCompleteWithError: 
* will still be called. */ 
0

fand ich eine Lösung für dieses Problem:

den Statuscode in der Antwort-Header zu erhalten, müssen Sie zuerst eine NSURLSessionDataTask starten.

Dies ruft die folgende Delegate-Methode URLSession: dataTask: didReceiveResponse: completionHandler:.

Bei diesem Verfahren können Sie zunächst den Statuscode der NSURLResponse Parameter prüfen (indem sie einem NSHTTPURLResponse Gießen) und schließlich den Abschluss-Handler rufen entweder mit NSURLSessionResponseBecomeDownload Ihre dataTask zu einem downloadTask zu konvertieren (die als verhalten Sie erwarten von NSURLSessionDownloadTask) oder NSURLSessionResponseCancel, um das Herunterladen einiger Daten zu vermeiden, die Sie nicht benötigen (z. B. wenn der Statuscode der Antwort 404 lautet).

Auch wenn Sie brauchen etwas, mit dem konvertierten NSURLSessionDownloadTask zu tun (wie es in einem Array oder einem Wörterbuch zu speichern oder die Daten Aufgabe mit dem neuen Objekt zu ersetzen), kann es in der URLSession erfolgen: dataTask: didBecomeDownloadTask:

Hoffe, das hilft jemandem!