iphone - son - ¿Mejores prácticas para enviar una gran cantidad de datos en segundo plano en un dispositivo iOS4?
si estoy conectado a wifi gasto datos? (5)
Tengo una aplicación que necesita enviar datos (usando POST) a un servidor. Esta función debe estar en uno de los sub-controladores de NavigationController y el usuario debe poder alejarse de este controlador y / o cerrar la aplicación (solo se admitirá iPhone4 / iOS4). ¿Debo usar subprocesos / NSOperations y / y enviar datos usando métodos asíncronos existentes? ¿Alguna idea / mejores prácticas cómo implementar esto?
Definitivamente, sugeriría un segundo subproceso para cualquier proceso de larga ejecución que deba ejecutarse mientras el usuario está haciendo otra cosa.
Otra cosa en la que tendrá que pensar es qué sucederá si el usuario inicia el proceso y luego presiona el botón de inicio. ¿Cómo se efectuará la interacción del servidor al ser interrumpida? ¿Puede continuar cuando el usuario ingrese a la aplicación? etc.
Me gustaría apoyar el post que menciona:
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
Pero también señale que es posible que también desee encapsular su unidad de trabajo en una subclase de NSOperation. Esto lo hará extremadamente reutilizable y, cuando se combine con NSOperationQueue, manejará el subprocesamiento automáticamente y lo que no. Luego, cuando desee cambiar su código, o que aparezca en una ubicación diferente en su aplicación, será trivial moverlo o editarlo.
Una nota sobre el uso de la cola de operaciones, es que en este caso realmente deseará enviar una solicitud de URL sincrónica desde la cola. Esto le permitirá no tener que preocuparse por las operaciones concurrentes. Aquí está el enlace que puede encontrar útil:
http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/
Sólo usaría NSURLConnection. Es un poco complicado si desea enviar varias partes / datos de formulario (consulte el ejemplo de SimpleURLConnections / PostController.m). Lo pegaría en el delegado de la aplicación, pero soy perezosa así.
No debe preocuparse por los subprocesos a menos que la E / S sin bloqueo (es decir, NSURLConnection) sea demasiado lenta. El enhebrado tiene sus propios gastos generales, y la comunicación entre subprocesos es un dolor, y los interbloqueos son terribles.
Lo que debe hacer es iniciar una tarea en segundo plano para permitir que su aplicación continúe ejecutándose mientras se encuentra en segundo plano (finalice la tarea en segundo plano en connectionDidFinishLoading: y connection: didFailWithError). Las aplicaciones en segundo plano tienen unos 10 minutos para terminar de ejecutar las tareas en segundo plano.
Use ASIHTTP y configure una Cola. Toda la información que necesitas puedes encontrarla aquí:
http://allseeing-i.com/ASIHTTPRequest/
Esta es la forma más fácil de lograr lo que quieres lograr. Para enviar gran cantidad de datos, es mejor enviar en segundo plano para mantener la interfaz de usuario receptiva. ASIHTTPRequest proporciona todos los métodos que necesita para eliminar varias consultas (es decir, verificaciones de progreso, devoluciones de llamada, etc.).
Es usado por toneladas de aplicaciones para iPhone.
OK, voy a responder mi propia pregunta. Primero, como dice tc, es mejor tener esta llamada en el delegado de la aplicación, para que la vista en el control de navegación se pueda cerrar. Segundo, marque el comienzo del procesamiento en segundo plano con beginBackgroundTaskWithExpirationHandler:
y endBackgroundTask:
con endBackgroundTask:
como esto:
.h:
UIBackgroundTaskIdentifier bgTask;
.metro:
- (void)sendPhoto:(UIImage *)image
{
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
NSLog(@"Sending picture...");
// Init async NSURLConnection
// ....
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"Picture sent.");
UIApplication *app = [UIApplication sharedApplication];
if (bgTask != UIBackgroundTaskInvalid) {
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}
Tienes 10 minutos antes de que iOS finalice tu aplicación. Puedes consultar esta hora con [app backgroundTimeRemaining]