In current development I need to synchronize tons of data with a server. The big “Synchronize” button in the settings or somewhere else isn’t a good solution, because user starts the application to use, but wait any system jobs. So the background synchronization is more better. I found the easiest way to do it and want to share a code snippet with you.
Run method in backgorund right from UIApplicationDelegate:
- (void) startBackgroundSynch{ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; BackgroundSynch *synch = [[[BackgroundSynch alloc] init] autorelease]; [synch startDownloading]; [pool release];} - (void)applicationDidFinishLaunching:(UIApplication *)application { [self performSelectorInBackground:@selector(startBackgroundSynch) withObject:nil]; // Override point for customization after app launch [window addSubview:viewController.view]; [window makeKeyAndVisible];}
The BackgroundSynch must create NSURLConnection and receives NSURLResponse(s). But the problem you’d face with is NSURLConnection’s events (didReceiveResponse, didReceiveData, connectionDidFinishLoading) are never called. And that’s a small trick.
@interface BackgroundSynch : NSObject{ NSMutableData *responseData; BOOL finished;} - (void) startDownloading;@end
#import "BackgroundSynch.h" @implementation BackgroundSynch - (void) startDownloadingWithUrl:(NSString*)urlString{ NSLog(urlString); NSURL *url = [NSURL URLWithString:urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30.0]; [request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"]; [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; } - (void) startDownloading{ [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; NSString *urlString = @"http://www.archive.org/download/BettyBoopCartoons/Betty_Boop_More_ Pep_1936_512kb.mp4"; [self startDownloadingWithUrl:urlString]; // THAT'S A TRICK >> finished = NO; while(!finished) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]]; }} ////// RECEIVING DATE FROM SERVER/// - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ responseData = [[NSMutableData alloc] init];} - (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)aData{ [responseData appendData:aData]; NSLog(@"DATA: %d", [responseData length]);} - (void) connectionDidFinishLoading: (NSURLConnection*) connection { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; [responseData release], responseData = nil; finished = YES;} -(void) connection:(NSURLConnection *) connection didFailWithError:(NSError *)error { [responseData release], responseData = nil; [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; finished = YES;} @end
Hope you were careful enough to find an while-loop depending at the end of “startDownloading”. It depends on boolean variable which tells if data is downloading or downloaded(failed).
Now user can normally work in GUI and data automatically synchronizes on background.


