I solved a similar problem by putting the insert processing in a background thread. But first I created a progress alert so the user couldn't manipulate the data store while it was inserting the entries.
This is basically the ViewControllers viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
// Only insert those not imported, here I know it should be 2006 entries
if ([self tableView:nil numberOfRowsInSection:0] != 2006) {
// Put up an alert with a progress bar, need to implement
[self createProgressionAlertWithMessage:@"Initilizing database"];
// Spawn the insert thread making the app still "live" so it
// won't be killed by the OS
[NSThread detachNewThreadSelector:@selector(loadInitialDatabase:)
toTarget:self
withObject:[NSNumber numberWithInt:[self tableView:nil
numberOfRowsInSection:0]]];
}
}
The insert thread was done like this
- (void)loadInitialDatabase:(NSNumber*)number
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int done = [number intValue]+1; // How many done so far
// I load from a textfile (csv) but imagine you should be able to
// understand the process and make it work for your data
NSString *file = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:@"filename"
ofType:@"txt"]
encoding:NSUTF8StringEncoding
error:nil];
NSArray *lines = [file componentsSeparatedByString:@"\n"];
float num = [lines count];
float i = 0;
int perc = 0;
for (NSString *line in lines) {
i += 1.0;
if ((int)(i/(num*0.01)) != perc) {
// This part updates the alert with a progress bar
// setProgressValue: needs to be implemented
[self performSelectorOnMainThread:@selector(setProgressValue:)
withObject:[NSNumber numberWithFloat:i/num]
waitUntilDone:YES];
perc = (int)(i/(num*0.01));
}
if (done < i) // keep track of how much done previously
[self insertFromLine:line]; // Add to data storage...
}
progressView = nil;
[progressAlert dismissWithClickedButtonIndex:0 animated:YES];
[pool release];
}
It's a bit crude this way, it tries to init the data storage from where it left of if the user happend to stop it the previous times...