2013-10-23 7 views
6

Ich führe eine NSURLSession-Hintergrundsitzung aus und ich versuche, einen Weg herauszufinden, wie die JSON-Antwort aus einem der NSURLDownloadTaskDelegate-Rückrufe abgerufen werden kann. Ich habe meine Sitzung so konfiguriert, dass sie JSON-Antworten akzeptiert.NSURLSessionDownloadTaskDelegate JSON-Antwort

NSURLSessionConfiguration *backgroundSession = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.Att.Locker.BackgroundUpload"]; 
backgroundSession.HTTPAdditionalHeaders = @{ @"Accept":@"application/json"}; 
session = [NSURLSession sessionWithConfiguration:backgroundSession delegate:uploader delegateQueue:nil]; 

Ich kann leicht JSON-Antwort für NSURLSessionDownloadTasks analysieren den folgenden Rückruf verwenden. Er schreibt die JSON-Antwort in Form von NSURL in die Sandbox.

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { 

    //Reading the Json response from the sandbox using the NSURL parameter 
} 

Mein Problem ist, wenn ich einen Fehler stoße über den Rückruf nicht genannt wird, scheint es nur im Fall eines erfolgreichen Download aufgerufen werden. Da ich eine Hintergrundsitzung verwende, kann ich keine NSURLSessionDataDelegate Rückrufe verwenden. Ich kann nur die NSURLSessionDownloadTaskDelegate und NSURLSessionTaskDelegate verwenden und während ich die Aufgabenantwort mit dem folgenden Rückruf abrufen kann. Ich sehe den JSON in der Antwort nicht.

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { 


NSHTTPURLResponse *response = (NSHTTPURLResponse *)downloadTask.response; 
NSDictionary *httpResponse = [response allHeaderFields]; 

NSLog(@"Response Header Fields:%@",[httpResponse allKeys]); 
} 

NSURLConnection hat einen didReceiveData Parameter, die uns ein NSData Objekt gibt, das wir die JSON-Antwort erhalten können. Ich sehe das nicht in den Delegierten Rückrufe für NSURLSession mit Ausnahme von NSURLDataTask, aber wir können Datenaufgaben im Hintergrund nicht verwenden, so wie sollen wir die JSON-Antwort erhalten? Jede Hilfe ist

geschätzt

EDIT:

ich dieses Problem in der Regel erfahren, während ich die App im Hintergrund laufen lasse (meistens, wenn es Speicher hinausgeworfen und nicht nur suspendiert). Ich habe die Callbacks in der AppDelegate implementiert und ich bin in der Lage, neu mit der Sitzung zu verknüpfen.Ich denke, didFinishDownloadingToURL wird nur im Falle der erfolgreichen Abschluss einer Aufgabe aufgerufen, aber wenn eine Aufgabe fehlschlägt gibt es keine Garantie wird aber genannt werden Andererseits wird didCompleteWithError jedes Mal aufgerufen, wenn ein Fehler auftritt.

+0

Könnten Sie bitte erklären, was Sie meinen, wenn "ich einen Fehler erhalte". Sie sollten unterscheiden zwischen Clientfehlern, die nicht einmal eine Verbindung generieren (z. B. eine ungültige URL), und einer Serverantwort, deren Statuscode eine fehlgeschlagene Anforderung angibt. Wenn Sie also einen Statuscode 200 (OK) erwarten und stattdessen 500 (Interner Serverfehler) erhalten, handelt es sich um einen Fehler der zweiten Kategorie: Die Verbindung ist nicht fehlgeschlagen, aber Ihre Anforderung ist semantisch fehlgeschlagen (möglicherweise wegen eines fehlerhaften Anfragetexts) , sagen wir missgebildete JSON). – CouchDeveloper

+0

Wenn ich einen Fehler sage, meine ich serverseitige Fehler, wo ich zusammen mit den Standard-HTTP-Fehlerantwortcodes auch einen JSON-Body –

+0

sage, zum Beispiel wenn ein GET 404 (Not Found) zusammen mit einer Fehlerantwort in JSON zurückgibt 'URLSession: downloadTask: didFinishDownloadingToURL:' wird nicht aufgerufen? – CouchDeveloper

Antwort

0

Mit einer Download-Aufgabe können Sie die Daten mit der didFinishDownloadingToURL wie angegeben erhalten.

Alle NSURLSession-Tasks haben diesen Delegaten ebenfalls. Wenn du hier reinkommst und der Fehler nicht null ist, dann hast du einen Fehler. Es muss nicht abgeschlossen werden, um hier rein zu kommen. Wenn es hier mit einem Fehler ankommt, wird der Delegat didFinishDownloadingToURL nicht aufgerufen.

Wenn kein Fehler auftritt und alle Ihre Daten heruntergeladen werden, werden beide Delegierten aufgerufen.

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error 
{ 
    NSLog(@"didCompleteWithError"); 
} 

EDIT:

So etwas hat nicht richtig eingerichtet zu setzen, wie es eine Möglichkeit hat, um die Daten zu erhalten.

Implementieren Sie application:handleEventsForBackgroundURLSession:completionHandler: in Ihrer AppDelegate, die Ihre App zurück an den Abschluss-Handler haken wird, um die Delegiertenanrufe zu erhalten?

Ich empfehle dringend die 2013 WWDC Sitzung # 705, "Whats New in Foundation Networking".Hintergrundsitzungsgespräch beginnt um ungefähr 32 Minuten und die Codedemo beginnt um 37:50

+0

Sie haben Recht, aber mein Problem ist, dass, wenn ich einen Fehler finde, didFinishDownloadToURL nicht aufgerufen wird und daher kann ich nicht die Daten (JSON Antwort) von meinem gesendet Server. Der Delegat für gemeinsame Aufgaben didCompleteWithError gibt mir nur ein NSError-Objekt, das für mich nicht nützlich ist. Da didFinishDownloadToURL nie aufgerufen wird, kann ich die JSON-Antwort, die den vom Server gesendeten Fehler enthält, nicht parsen. –

+0

Im Falle eines Serverfehlers sollten Sie die JSON-Datei immer noch innerhalb der Datei didFinishDownloadingToURL abrufen. Nur Client-Fehler (kein Internet usw.) lösen den Fehler didCompleteWithError mit en aus. Wenn Sie eine gültige Antwort vom Server zurück erhalten (auch wenn es ein Fehler in JSON ist), wie ich sagte, sollten Sie immer noch zurück – RyanG

+0

didFinishDownloadingToURL wird nicht aufgerufen, wenn meine App im Hintergrund ist. Ich sehe nur, dass didCompleteWithError aufgerufen wird. Und ich benutze ein Werkzeug, um HTTP-Verkehr zu überwachen, und ich sehe die JSON-Antwort kommen zurück, aber an dieser Stelle habe ich keine Ahnung, wie man es in meiner App bekommen. –