Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice to send a lot of data in background on iOS4 device?

Tags:

I have an app that needs to send data (using POST) to a server. This function has to be on one of the NavigationController sub-controllers and user should be able to navigate away from this controller and/or close the app (only iPhone4/iOS4 will be supported). Should I use threads/NSOperations or/and send data using existing asynchronous methods? Any ideas/best practices how to implement this?

like image 269
cocoapriest Avatar asked Oct 13 '10 23:10

cocoapriest


2 Answers

OK, I'll answer my own question. First, like tc said, it's better to have this call on the application delegate, so that the View in the NavigationController can be closed. Second, mark beginning of the background processing with beginBackgroundTaskWithExpirationHandler: and end it with endBackgroundTask: like this:

.h:

UIBackgroundTaskIdentifier bgTask;

.m:

- (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;   } } 

You have 10 minutes before iOS terminates your app. You can check this time with [app backgroundTimeRemaining]

like image 180
cocoapriest Avatar answered Dec 03 '22 09:12

cocoapriest


I'd just use NSURLConnection. It's a bit tricky if you want to send multipart/form-data (see the SimpleURLConnections/PostController.m example). I'd stick it in the app delegate, but I'm lazy like that.

You shouldn't worry about threads at all unless non-blocking I/O (i.e. NSURLConnection) is too slow. Threading has its own overheads, and inter-thread communication is a pain, and deadlocks are terrible.

What you do need to do is start a background task to allow your app to continue executing while backgrounded (end the background task in connectionDidFinishLoading: and connection:didFailWithError). Backgrounded apps are given about 10 minutes to finish executing background tasks.

like image 45
tc. Avatar answered Dec 03 '22 09:12

tc.