I am wondering if there are any recommendations for improving responsiveness to the user interface when performing Core Data savings (not retrieval) with large sets of managed objects.
The application I'm working on requires downloading a fairly large amount of data at set intervals from the web service to completion. At each interval, a data packet is loaded, formatted to managed objects, and stored in Core Data. Since this process can take up to 5 minutes until it is completely completed, simply adding a boot screen until everything is over is not an option, it takes too much time. I'm also interested in making frequent entries in Core Data, rather than one large entry at the end, to keep the memory level low. Ideally, I would like the user to be able to continue using the rest of the application in normal mode while simultaneously loading and writing these large datasets into Core Data.
Unfortunately, it seems that when I try to save my insertions, which I put in the context of the managed object for each batch, this save operation blocks the userβs interaction with the rest of the application (scrolling tables, touching a button, etc.) until it is completed. For those short periods of time when the master data is saved, the application is very unresponsive.
Naturally, I tried to make these reductions smaller by reducing the size of individual batches that load per interval, but in addition to the inconvenience of making the whole process longer, there will still be cases when the swipe user is not captured, because at that particular time the main data was saved . Downsizing just makes it less likely that missed wipes or missed touches will happen, but they still seem to happen often enough to be uncomfortable.
For the inserts themselves, I tried to use two different implementations: insertNewObjectForEntityForName: inManagedObjectContext, as well as setValuesForKeysWithDictionary. Both demonstrate the problem described above.
I tried prototyping a much simpler test to see the performance both in the simulator and on the device, important elements are presented here. This example does not actually download anything from the Internet, but simply writes a whole bunch of material to the main data at set intervals from the TableViewController. I would like to know if anyone has any suggestions for improving the reaction.
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(doTimerWork:) userInfo:nil repeats:YES]; } -(void) doTimerWork:(id)sender { for (int i = 0; i < 1000; i++) { Misc * m = (Misc*)[NSEntityDescription insertNewObjectForEntityForName:@"Misc" inManagedObjectContext:managedObjectContext]; m.someDate = [NSDate date]; m.someString = @"ASDASDASD"; m.someOtherString = @"BLAH BLAH BLAH"; m.someNumber = [NSNumber numberWithInt:5]; m.someOtherNumber = [NSNumber numberWithInt:99]; m.someOtherDate = [NSDate date]; } NSError *error; if (![managedObjectContext save:&error]) { NSLog(@"Experienced an error while saving to CoreData"); } }