NSURLSesión: carga en segundo plano y luego llama a un service api

Estaba intentando utilizar la nueva API de transferencia de background ios7 para upload algunas fotos a un server. lo que sucedió ahora es 1) cargamos los bytes a s3 2) llamamos a un service api para 'completar' la carga

Miré este documento y parece que NSURLSession no es compatible con la tarea 'datos'. ¿Eso significa que no puedo hacer el paso 2 en segundo plano después de que se haya realizado la carga real?

Si desea una solución más sencilla que volver a utilizar NSURLSessionDownloadTask para su llamada API "completada", puede realizar una llamada rápida http durante la callback en:

-URLSession:task:didCompleteWithError:

Para S3 con tarea de background, ve mi respuesta aquí.

Otro buen recurso es el código de muestra de manzana aquí y busque "Transferencia de background simple"

Debes crear una tarea de carga y uploadla desde un file local. Mientras su aplicación esté ejecutando los methods de delegado de NSURLSessionTaskDelegate, se completará específicamente al finalizar la carga:

  /* Sent as the last message related to a specific task. Error may be * nil, which implies that no error occurnetworking and this task is complete. */ -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error; 

Si su aplicación pasó a segundo plano o incluso fue eliminada por iOS (y no por el usuario), su aplicación se despertaría con

 URLSessionDidFinishEventsForBackgroundURLSession 

Y luego se llamará a su método de delegación de NSURLsession

 - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session 

La forma en que debe crearlo es la siguiente, en su appDelegate add

  - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler { /* Store the completion handler. The completion handler is invoked by the view controller's checkForAllDownloadsHavingCompleted method (if all the download tasks have been completed). */ self.backgroundSessionCompletionHandler = completionHandler; } 

Luego, en su controller / class model, agregue

  /* If an application has received an - application:handleEventsForBackgroundURLSession:completionHandler: message, the session delegate will receive this message to indicate that all messages previously enqueued for this session have been delivenetworking. At this time it is safe to invoke the previously stonetworking completion handler, or to begin any internal updates that will result in invoking the completion handler. */ - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session { APLAppDelegate *appDelegate = (APLAppDelegate *)[[UIApplication shanetworkingApplication] delegate]; if (appDelegate.backgroundSessionCompletionHandler) { void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler; appDelegate.backgroundSessionCompletionHandler = nil; completionHandler(); } NSLog(@"All tasks are finished"); } 

NSURLSessions tiene un método de delegado URLSessionDidFinishEventsForBackgroundURLSession que se llama después de que la session completa todas sus tareas. Creo que deberías hacer una llamada api.

 - (void)applicationDidEnterBackground:(UIApplication *)application { if([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) { NSLog(@"Multitasking Supported"); __block UIBackgroundTaskIdentifier background_task; background_task = [application beginBackgroundTaskWithExpirationHandler:^ { //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"); while(TRUE) { NSLog(@"Background time Remaining: %f",[[UIApplication shanetworkingApplication] backgroundTimeRemaining]); [NSThread sleepForTimeInterval:1]; //wait for 1 sec } //#### background task ends //Clean up code. Tell the system that we are done. [application endBackgroundTask: background_task]; background_task = UIBackgroundTaskInvalid; }); } else { NSLog(@"Multitasking Not Supported"); } } 

poner este código en el file appdelegate.m

Prueba este código, espero que te sirva de ayuda.