6

Inizialmente pensavo che se un NSURLSessionDownloadTask termina con successo il metodo URLSession:downloadTask:didFinishDownloadingToURL: verrà chiamato, se fallisce per qualche motivo - URLSession:task:didCompleteWithError:. Funziona come previsto sul simulatore (solo uno di questo metodo è chiamato per un'operazione di download) ma sul dispositivo non è questo il caso: in caso di errore entrambi questi metodi sono chiamati, URLSession:downloadTask:didFinishDownloadingToURL: è il primo. (entrambi questi metodi passano lo stesso compito nei parametri)Gestione NSURLSessionDownloadTask fallita

C'è qualcosa che mi manca?

+0

Ho notato lo stesso comportamento in DidFinishDownloadingToURL è chiamato a fianco di doneCompleteWithError. Questo ha causato enormi problemi per noi. Come hai lavorato intorno a questo? In questo caso, la posizione – RunLoop

+0

potrebbe essere chiusa. Puoi controllare questo? – AsifHabib

risposta

1

blocco usare il completamento invece di delegato:

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

Nota: se non si ottiene la coda principale, eventuali aggiornamenti relativi all'interfaccia utente sarà in ritardo che provoca comportamenti insospettabili.

+1

Mi piacerebbe che i miei utenti finissero i download quando la mia app entra in modalità background, quindi non posso usare i blocchi di completamento invece di un delegato (dato che sto usando la sessione in background) – dariaa

+0

. Che ne dici di utilizzare una BOOL globale per sapere se hai elaborato la risposta? –

+0

Beh, certo che può esserci una soluzione, ma volevo approfondire la comprensione. È un comportamento previsto o è un bug che dovrebbe essere segnalato, ecc.BTW un flag 'BOOL' non è la scelta migliore qui, poiché in' URLSession: downloadTask: didFinishDownloadingToURL: '(che viene chiamato prima) uno di solito copia il file nella directory dei documenti per un'ulteriore elaborazione. Sarebbe bello sapere a quel punto se il download è terminato correttamente o con errori. – dariaa

-1

NSURLSessionDownloadTask è una sottoclasse di NSURLSessionTask, che ha una proprietà error. Potresti verificarlo nel tuo metodo delegato URLSession:downloadTask:didFinishDownloadingToURL: prima di provare a copiare il tuo file?

+0

La proprietà error rimane nil a meno che non si tratti di un errore lato client. –

1

Secondo la documentazione Apple sotto NSURLSessionDownloadDelegate È un comportamento standard.

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

ho trovato una soluzione a questo problema:

Per ottenere il codice di stato nell'intestazione della risposta, si deve prima iniziare una NSURLSessionDataTask.

Questo chiamerà il seguente metodo delegato URLSession: dataTask: didReceiveResponse: completionHandler:.

In questo metodo, è possibile selezionare il codice di stato dei parametri NSURLResponse (gettandola a un NSHTTPURLResponse) e, infine, chiamare il gestore di completamento sia con NSURLSessionResponseBecomeDownload per convertire il vostro dataTask ad un downloadTask (che si comporterà come ci si aspetterebbe da un NSURLSessionDownloadTask) o NSURLSessionResponseCancel per evitare di scaricare alcuni dati non necessari (ad esempio se il codice di stato della risposta è 404).

Inoltre, se hai bisogno di fare qualcosa con il convertito NSURLSessionDownloadTask (come la memorizzazione in un array o di un dizionario o sostituendo il compito di dati con il nuovo oggetto), può essere fatto nel URLSession: dataTask: didBecomeDownloadTask:

Spero che questo aiuti qualcuno!