6

Oryginalnie myślałem, że jeśli NSURLSessionDownloadTask zakończy się pomyślnie, to zostanie wywołana metoda URLSession:downloadTask:didFinishDownloadingToURL:, jeśli z jakiegoś powodu zawiedzie - URLSession:task:didCompleteWithError:. Działa zgodnie z oczekiwaniami na symulatorze (tylko jedna z tych metod jest wywoływana dla jednego zadania pobierania), ale na urządzeniu tak nie jest: w przypadku niepowodzenia obie metody są wywoływane, URLSession:downloadTask:didFinishDownloadingToURL: jest pierwszą. (obie te metody przechodzą to samo zadanie w parametrach)Obsługa błędu NSURLSessionDownloadTask

Czy jest coś, czego mi brakuje?

+0

Zauważyłem to samo zachowanie w tym, że DidFinishDownloadingToURL jest wywoływane obok didCompleteWithError. To spowodowało dla nas ogromne problemy. Jak sobie z tym poradziłeś? – RunLoop

+0

lokalizacja może być w tym przypadku pusta. Czy możesz to sprawdzić? – AsifHabib

Odpowiedz

1

Zastosowanie ukończenie bloku zamiast delegata:

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 
     }); 
}]; 

Uwaga: Jeśli nie dostać główną kolejkę, każda zmiana związane z interfejsem użytkownika będzie opóźniony, co powoduje nieoczekiwane zachowania.

+1

Chciałbym, aby moi użytkownicy mieli ukończone pobieranie, gdy moja aplikacja przechodzi w tryb tła, więc nie mogę używać bloków ukończenia zamiast delegata (ponieważ używam sesji w tle) – dariaa

+0

Dostaję. A co powiesz na użycie globalnego BOOL-a, aby wiedzieć, czy przetworzono odpowiedź? –

+0

Oczywiście, może istnieć obejście, ale chciałem trochę głębiej zrozumieć. Czy jest to oczekiwane zachowanie, czy jest to błąd, który należy zgłosić itp.BTW flaga 'BOOL' nie jest najlepszym wyborem, ponieważ w' URLSession: downloadTask: didFinishDownloadingToURL: '(która jest nazywana pierwszą) zwykle kopiuje plik do katalogu dokumentów w celu dalszego przetwarzania. Byłoby miło wiedzieć, czy pobieranie zakończyło się sukcesem, czy z błędem. – dariaa

-1

NSURLSessionDownloadTask to podklasa NSURLSessionTask, która ma właściwość error. Czy możesz sprawdzić to w swojej delegowanej metodzie URLSession:downloadTask:didFinishDownloadingToURL: przed próbą skopiowania pliku?

+0

Właściwość błędu pozostaje pusta, chyba że jest to błąd po stronie klienta. –

1

Zgodnie z dokumentacją Apple pod numerem NSURLSessionDownloadDelegate Jest to standardowe zachowanie.

/* 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

znalazłem rozwiązanie tego problemu:

Aby uzyskać kod stanu w nagłówku odpowiedzi, należy najpierw rozpocząć NSURLSessionDataTask.

Spowoduje to wywołanie następującej metody delegowania: URLSession: dataTask: didReceiveResponse: completionHandler:.

W tej metodzie, można najpierw sprawdzić kod stanu parametrów NSURLResponse (oddając go do NSHTTPURLResponse) i wreszcie wywołać obsługi zakończenia albo NSURLSessionResponseBecomeDownload zamienić dataTask do downloadTask (która będzie zachowywać się jak można oczekiwać od NSURLSessionDownloadTask) lub NSURLSessionResponseCancel, aby uniknąć pobierania niektórych danych, których nie potrzebujesz (na przykład, jeśli kod stanu odpowiedzi to 404).

Ponadto, jeśli trzeba zrobić coś z przebudowanej NSURLSessionDownloadTask (jak przechowywanie go w tablicy lub słownika lub zastąpienie zadanie danych z nowego obiektu), można to zrobić w URLSession: dataTask: didBecomeDownloadTask:

Mam nadzieję, że to komuś pomaga!

Powiązane problemy