2012-01-14 12 views
20

Cuando mi aplicación se descarga inicialmente, el usuario necesita descargar un archivo grande como 200 MB (límite superior). Definitivamente no puedo esperar que el usuario mantenga la aplicación abierta hasta que se descargue este archivo. Para que él/ella cierre la aplicación &, la aplicación se pondrá en segundo plano.iOS Antecedentes descarga cuando la aplicación no está activa

¿Cómo puedo seguir descargando el archivo en este escenario? ¿Es esto posible en iOS?

+0

¿finalmente pudo descargar ese archivo en segundo plano? – Mahesh

+0

Consulte la respuesta de MMR a continuación. Verdadero fondo 'NSURLSession' es la mejor manera de lograr esto hoy en día. Todas estas otras respuestas son anteriores a esta técnica. Si tiene una descarga pequeña que necesita menos de 3 minutos para finalizar, la tarea de fondo está bien enfocada, pero para grandes descargas de fondo, use el fondo 'NSURLSession'. – Rob

Respuesta

7

Es posible iniciar una tarea en segundo plano cuando comience la descarga:

aplicaciones que están pasando a un segundo plano puede solicitar una cantidad adicional de tiempo para terminar las tareas importantes de última hora.

Executing a Finite-Length Task in the Background

Sin embargo, una tarea de este tipo se limita a una cantidad indefinida de tiempo de ejecución por el sistema. Sin embargo, una descarga de archivos de 200Mb puede ser una tarea demasiado grande en este caso.

+0

Sí. Es posible que desee utilizar una biblioteca de red que le permita pausar y reanudar las descargas desde donde se quedaron, de modo que el usuario no tenga que volver a empezar desde el principio si la descarga se interrumpe. ASIHttpRequest puede hacer esto, pero ya no es compatible ya que no funciona con ARC. –

+2

ya no es correcto. En ARC para ASIHttp, puede usar una biblioteca estática compilada con un entorno que no sea ARC. – samfisher

37

Añadir a continuación en su - (void)applicationDidEnterBackground:(UIApplication *)application

UIApplication *app = [UIApplication sharedApplication]; 
UIBackgroundTaskIdentifier bgTask; 

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
     [app endBackgroundTask:bgTask]; 
}]; 

y que son buenos para ir ... Tengo esto en uno de mi descarga de aplicaciones publicadas gerente

Esto funciona muy bien. También puede verificar cuánto tiempo tiene, ya que Apple solo habilita tareas de fondo de 10 minutos. Uso:

NSTimeInterval ti = [[UIApplication sharedApplication]backgroundTimeRemaining]; 
NSLog(@"backgroundTimeRemaining: %f", ti); // just for debug 
+0

¿Entonces con esto puedo descargar? ¿Hay algún límite de tiempo como @nick dice arriba? –

+10

sí ... la manzana habla sobre el límite de tiempo ... pero puedo descargar un archivo con un tamaño de 800 mb con el código anterior ... y la aplicación está en la tienda de aplicaciones ... – Saurabh

+0

wow !! ese comentario tuyo es información preciosa @Saurabh. ¡¡Gracias!! – samfisher

3

AFNetworking permite llevar a cabo la operación pesada en el fondo.

AFNetworking La biblioteca es una excelente combinación de NSURLConnection y NSOperationQueue.Esta biblioteca se utiliza para la descarga asíncrona en segundo plano que no afecta a la otra aplicación.

AFNetworking le permite manejar la descarga con ExpirationHandle, es decir, si de alguna manera durante la descarga se pierde la conexión, se conectará de nuevo.

Biblioteca Fuente para AFNetworking

Fuente de referenciaAFNetworking works in Background

de Apple Reference EnlaceApple

ejecución en segundo plano y multitarea Apple

5

En una de mis aplicaciones, estaba cargando una gran cantidad de datos. Definitivamente no puedo esperar que el usuario mantenga la aplicación en primer plano hasta que se descarguen los datos. Solo uso el siguiente código para descargar los datos mientras la aplicación está en segundo plano.Su funcionando correctamente :-)
favor vaya a través siguientes pasos:

1) Usar la siguiente línea en el archivo de cabecera de ViewController

@property (nonatomic) UIBackgroundTaskIdentifier backgroundTask; 

síntesis que en el archivo .m.

2) en viewDidLoad asigno UIBackgroundTaskIdentifier como:

self.backgroundTask = UIBackgroundTaskInvalid; 

3) Uso siguiente línea de código, aquí sólo estoy guardando en el interior método getDataFromServer beginBackgroundTaskWithExpirationHandler: bloque.

 self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ 

     [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask]; 
     self.backgroundTask = UIBackgroundTaskInvalid; 
    }]; 

    /* Here your downloading Code, let say getDataFromServer method */ 

    [self getDataFromServer]; // Its dummy method 

    /* Your downloading Code End Here */ 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask]; 
     self.backgroundTask = UIBackgroundTaskInvalid; 
    }); 

4) Si desea comprobar el tiempo restante para descargar los datos de antecedentes, son de la línea siguiente en applicationDidEnterBackground: (UIApplication *) Método delegado aplicación de AppDelegate:

 NSLog(@"Background time remaining = %.1f seconds", [UIApplication sharedApplication].backgroundTimeRemaining); 
+0

Respuesta clara como el cristal, muchas gracias por la ayuda – byJeevan

0
#pragma mark - View Loading handling 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; 
} 

#pragma mark - Background handling when application goes background 
UIBackgroundTaskIdentifier background_task; 
- (void)appDidEnterBackground:(NSNotification *)notification { 
    UIApplication *application = [UIApplication sharedApplication]; 
    if([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) 
    { 
     NSLog(@"Multitasking Supported"); 
     if (background_task == UIBackgroundTaskInvalid) { 
      background_task = [application beginBackgroundTaskWithExpirationHandler:^ { 
       NSLog(@"Background task expiration\n"); 
       //Clean up code. Tell the system that we are done. 
       [application endBackgroundTask: background_task]; 
       background_task = UIBackgroundTaskInvalid; 
      }]; 
      //To make the code block asynchronous 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       //### background task starts 
       NSLog(@"Running in the background\n"); 
       for(int cnt=0; cnt<10; cnt++) //while(TRUE) 
       { 
        NSLog(@"Background time Remaining: %f",[[UIApplication sharedApplication] backgroundTimeRemaining]); 
        [NSThread sleepForTimeInterval:1]; //wait for 1 sec 
       } 
       //#### background task ends 
       //Clean up code. Tell the system that we are done. 
       NSLog(@"here you can do something before it really enters background"); 
       [NSThread sleepForTimeInterval:1]; //wait for 1 sec 
       [application endBackgroundTask: background_task]; 
       background_task = UIBackgroundTaskInvalid; 
      }); 
     } 
     else 
     { 
      NSLog(@"Multitasking Not Supported"); 
     } 
    } 
} 

Puede saber más de este slide.
Acabo de hacer algunas modificaciones simples útiles del fragmento de esta diapositiva. Espero que esto ayude.

0

Cree una aplicación de iOS de noticias; no es una aplicación de iOS estándar.

aplicaciones iOS: Standart

  • no pueden descargar los datos cuando se cierra.
  • puede descargar datos en tiempo limitado cuando se empuja al fondo.
  • No hay tiempo suficiente para descargar 200mb.

Las aplicaciones NewsStand tienen un privilegio de tiempo extra para descargar cuando están cerradas o inBackground. Una vez cada 24 horas, tienen el privilegio de responder a una llamada de delegado RemoteContentReady.

Crear una aplicación newsStand no es diferente a construir una aplicación estándar de iOS. Simplemente lo marcará como la aplicación newStand.

Luego tendrá privilegios para ejecutar el código que está dentro de la delegación remoteContentReady.

Para recibir la señal RemoteContentReady, debe enviar una señal desde su servidor (C#, php, bla bla).

No en todas las aplicaciones de iOS. Algo así como una señal de notificación remota. Es posible que necesite la certificación SSL para su sitio web con el fin de lograr esto.

Saludos

+0

No sabía esto, gracias por compartir @ Add080bbA – Prashant

5

Usted podría utilizar NSURLSession introdujo en iOS 7.0 y posterior para continuar con la carga/descarga de un archivo incluso cuando se suspende la aplicación.

Apple documentation

La clase NSURLSession y clases relacionadas proporcionan una API para descarga de contenidos. Esta API proporciona un amplio conjunto de métodos de delegado para admitir la autenticación y le permite a su aplicación realizar descargas en segundo plano cuando su aplicación no se está ejecutando o, en iOS, mientras su aplicación está suspendida.

Y

sesiones de fondo le permiten realizar cargas y descargas de contenido en el fondo, mientras que su aplicación no se está ejecutando. Puede crear una configuración de sesión de fondo llamando al backgroundSessionConfiguration: método en la clase NSURLSessionConfiguration .

Un buen tutorial para usar NSURLSession en este link.

+0

Esta es la respuesta correcta. ¡Usa el fondo 'NSURLSession'! – Rob

Cuestiones relacionadas