2011-07-28 15 views
6

Necesito implementar la publicación de algunos datos en un servidor web en segundo plano. Solo para aclarar, por "en segundo plano", no me refiero a la forma normal de mostrar un ícono giratorio y publicar datos en un servicio web utilizando algo así como un método AsyncTask o ASIHTTPRequest . Necesito mantener una cola de datos que un Thread puede comenzar a procesar y publicar en un servicio web de manera asidua mientras el usuario está trabajando en la aplicación.Llamadas de red en segundo plano: iOS

Estoy buscando ayuda para diseñar una cola así, especialmente en algunos casos extremos, como el usuario recibe una llamada, cierra la sesión mientras la publicación está sucediendo, el usuario deja la aplicación para ir a una diferente mientras que una publicación está sucediendo y similares. ¿Cómo manejarías estos casos? ¿Hay algún código fuente que puedas recomendar que haga esto?

Gracias,
Teja.

+1

usted debe leer en [Grand Central Dispatch] (http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html) – bshirley

Respuesta

3

He empezado a utilizar NSOperationQueue en mi propio trabajo últimamente, para el control de las solicitudes de red fondo . NSOperation trata con la mayor parte del código repetitivo necesario para ejecutar tareas de forma asíncrona (como operaciones de red) en hilos en el fondo (o en primer plano, si es necesario para actualizaciones de UI).

También permite dependencias entre colas; por ejemplo, utilizo dos colas en mi aplicación:

Las primeras descargas de imágenes programadas, con una concurrencia máxima de 2 a la vez, en segundo plano.Cada descarga de imagen tiene un controlador de finalización correspondiente (como NSBlockOperation) que depende de que se complete la descarga de la imagen. Estas operaciones se encuentran en el [NSOperationQueue mainQueue], que opera en el hilo principal, lo que les permite actualizar la IU (específicamente, la correspondiente UIImageView).

Tenga en cuenta que NSOperation y NSOperationQueue no son para solicitudes de red solamente, pero cualquier operación que se puede dividir en tareas atómicas y programar al mismo tiempo.

Here son los documentos de introducción de Apple sobre el tema.

2

Al haber implementado algo similar yo mismo, recomendaría usar un servicio y no un hilo para hacer llamadas de red. De esa manera, incluso si tu actividad se mata, estás seguro de que se ejecutarán tus llamadas de red.

Luego de aplicar la cola le sugiero que eche un vistazo en IntentService (http://developer.android.com/reference/android/app/IntentService.html)

de los documentos:

IntentService es una clase base para los servicios que manejan solicitudes asíncronas (expresadas como Intents) bajo demanda. Los clientes envían solicitudes a través de startService (Intent) llamadas; el servicio se inicia según sea necesario, maneja cada intento a su vez utilizando un hilo de trabajo, y se detiene a sí mismo cuando se queda sin trabajo.

Este patrón de "procesador de colas de trabajo" se utiliza comúnmente para descargar las tareas desde el hilo principal de una aplicación. La clase IntentService existe para simplificar este patrón y ocuparse de la mecánica. Para usarlo, amplíe IntentService e implemente onHandleIntent (Intención). IntentService recibirá los Intents, iniciará un hilo de trabajo y parará el servicio según corresponda.

Todas las peticiones son manejadas en un solo subproceso de trabajo - que puede tomar como tiempo que sea necesario (y no bloquear el bucle principal de la aplicación), pero sólo una solicitud serán procesados ​​a la vez.

Si su aplicación es suficiente, se puede utilizar sendBroadCast() para compartir información y notificaciones entre su actividad y el IntentService sencilla

+1

de acuerdo, pero Necesito implementar esto en iOS, Blackberry y Android, así que esperaba poder evitar los servicios. –

+0

bien Entiendo tu punto, vi que tu título de publicación tenía iOS solo hasta que presenté mi respuesta. –

+1

Las aplicaciones de Android están escritas en Java, mientras que las aplicaciones de iOS están escritas en Objectivo-C. No creo que puedas aprovechar el mismo código. (Lo sé, el paquete NDK admite código nativo en Android). Esto puede ser mejor como 3 preguntas separadas. – CrackerJack9

0

Crear un conjunto unitario que encapsulan un hilo:

En la inicialización del objeto:

[NSThread detachNewThreadSelector:@selector(mainPosterThread) toTarget:self withObject:nil]; 

- (void)mainDownloaderThread 
{ 

    if([NSThread respondsToSelector:@selector(setThreadPriority:)]) 
    { 
     [NSThread setThreadPriority:0.1]; 
    } 
    NSString *urlToDownload = nil; 
    while(shouldRun) 
    { 
     // Take next data to post in a queue (lastObject of a NSArray for example) 
     if(nextDataToPost) 
     { 
      // Post 
     } 
     else 
     { 
      // Sleep for some time. 
     } 
    } 
} 

Usted también puede tener métodos para detener/iniciar el hilo mientras que la aplicación vaya de fondo/primer plano en una dispositivo compatible con múltiples tareas. Si no se admite la multitarea, guarde los datos de la cola en el momento de la detención (si no demasiado) y restablézcalos al inicio. El mayor problema es gestionar la posibilidad de cancelar la carga actual mientras la aplicación finaliza.

0

Este es un problema que he estado perfeccionando en cada nueva aplicación que escribo. Básicamente, quería la funcionalidad de red que es asíncrona y la escribí usando funcionalidad nativa. Estaría encantado de mostrarte algo de este código si estás interesado.

Antes que nada, sugiero que realice todas las llamadas de red en el hilo principal de forma asíncrona en lugar de sincronizar, utilizando un delegado. De esta forma, la serialización/sincronización/concurrencia no es un problema. Y como las clases son delegadas de la red, acabo de enviar una clase a una nueva conexión que tiene una nueva instancia de delegado.

[[NSURLConnection alloc] initWithRequest:request delegate:del] autorelease]; 

e.g. 
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
Cuestiones relacionadas