example datatask ios session download nsurlsession

ios - datatask - urlsession swift 4 example



Conversión de NSURLSessionDataTask en una tarea de descarga con soporte de fondo (1)

Esta pregunta es un poco difícil de dar una respuesta clara, me parece, que los 3 principales factores de carga de URL (sessionType, taskType, FG / BG creation) están restringidos por tus diseños.

Como la sesión guarda una copia profunda de la configuración (que determina el tipo de naturaleza de la sesión predeterminada / BackGround / efímera) , después de iniciar la sesión (en nuestro caso: su sesión de tipo predeterminado) NO puede modificar la configuración-Objeto para esta sesión actual más. Entonces, si su diseño NO permite hacer una nueva Tarea asociada con una nueva (afortunadamente) sesión tipo BG, no hay forma de convertir mágicamente una "dataTask" en una "downloadTask".

Tenga en cuenta que NSURLSessionDataTask y NSURLSessionDownloadTask son subclases de NSURLSessionTask , NSURLSessionDataTask y NSURLSessionDownloadTask que manejan los datos de respuesta entrantes (por segmentos VS en cuanto a archivos respectivamente) implementados de manera muy diferente por los marcos.

Una atractiva ilusión puede ser este atractivo método URLSession:dataTask:didBecomeDownloadTask: pero debe crear una nueva tarea (DownloadTask de hecho) asociada con la sesión actual (profundamente estampada por su tipo predeterminado configurado anteriormente) , y dejar la tarea original ( dataTask) como huérfano. Según entiendo, su diseño NO puede tomar esta opción debido a la creación adicional de la tarea, y deberá permanecer con la configuración de sesión de tipo predeterminado.

URLSession: dataTask: didBecomeDownloadTask: realmente debería nombrarse como URLSession: dataTask: wasReplacedByDownloadTask:

La única solución simple que tengo ahora es que, en Data-Task-Delegate (la clase implementa el protocolo NSURLSessionDataDelegate) al recibir URLSession: dataTask: didReceiveData: initial call, comienza a almacenar esos datos por partes de cierta manera (almacenar en un archivo temporal, tal vez, simulando la acción predeterminada de NSURLSessionDownloadTask) , y asegúrese de ejecutar esta delegación de forma asincrónica en NSOperationQueue (supongo que su "capacidad de fondo" significa hilo secundario, que puede ser ofrecido por NSOperationQueue subrayando el mecanismo de subprocesamiento) , hasta que se complete la descarga, luego verifique su almacenamiento para resultados acumulados (si maneja cualquier error y / o transfiera el archivo a otro lugar) en este método general NSURLSessionTaskDelegate "URLSession: task: didCompleteWithError:"

Al hacerlo, convierte la solicitud (representada por una sesión NSURLSessionDataTask) en una descarga (no una sesión NSURLSessionDownload) . Para que esta conversión se realice en una cola en segundo plano, proporcione un valor no nulo para el (último) parámetro (método de sesión / tarea) de este delegado: de lo contrario, la cola de operaciones en serie no cumplirá con su "capacidad de fondo".

NSOperationQueue* aQueue = [[NSOperationQueue alloc] init]; NSURLSession *sessione = [NSURLSession sessionWithConfiguration:configuratione delegate:self delegateQueue: aQueue];

Otras ideas serán ejecutar manualmente múltiples objetos NSOperation, anular sus métodos de inicio para asegurar la ejecución asíncrona para su tarea de descarga, que podría ser un poco complicado.

Cualquier otra persona, que tenga mejores soluciones, por favor traiga más chispas ... o corríjanme por cualquier error que haya cometido.

Necesito descargar con capacidad de fondo ciertos archivos (no todos), después de verificar los encabezados (de longitud y tipos), pero tiene que estar en la misma operación, sin crear una nueva tarea / solicitud (porque a veces obtengo una error del servidor debido a muchas conexiones en un corto período de tiempo). Entonces comienzo la Tarea:

NSURLSessionConfiguration *configuratione = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *sessione = [NSURLSession sessionWithConfiguration:configuratione delegate:self delegateQueue:nil]; NSURLSessionDataTask *datatask = [sessione dataTaskWithRequest:request]; [datatask resume];

Entonces, sé que es posible convertir una tarea de datos en una tarea de descarga al recibir la primera respuesta, con este delegado:

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { if(XXXXXXXXXX){ NSLog(@"transform into a download"); completionHandler(NSURLSessionResponseBecomeDownload); }else{ NSLog(@"Keep loading normally"); completionHandler(NSURLSessionResponseAllow); } }

Sin embargo, dado que Data Tasks no puede usar BackgroundSessionConfiguration, supongo que la nueva descarga creada utilizará la misma configuración de sesión predeterminada. ¿Cómo puedo mantener esa descarga ejecutándose en segundo plano? ¿Hay alguna forma de cambiar su sesión a una de fondo? ¿O cuál sería el enfoque?