In my project I should download a JSON file made in this way:
[{"id":"2","n":"One"},{"id":"2","n":"Two"},{"id":"2","n":"Three"},...]
my code is this:
- (void) startPopulate:(NSArray *)array{
NSManagedObjectContext *context = [[self sharedAppDelegate] managedObjectContext];
NSFetchRequest *fetchRequest=[NSFetchRequest fetchRequestWithEntityName:@"Myentity"];
NSError *error = nil;
for (id element in array){
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"id == %@",[element objectForKey:@"id"]]];
Myentity *myE = [[context executeFetchRequest:fetchRequest error:&error] lastObject];
//update
if (myE != nil){
myE.id_e = [element objectForKey:@"id"];
myE.name = [element objectForKey:@"n"];
}
//new element
else{
Myentity *myE = [NSEntityDescription insertNewObjectForEntityForName:@"Myentity" inManagedObjectContext:context];
myE.name = [element objectForKey:@"n"];
myE.id_e = [element objectForKey:@"id"];
}
}
if (![context save:&error]) {
NSLog(@"couldn't save: %@", [error localizedDescription]);
}
else{
NSLog(@"DB UPDATED");
}
}
As you can see I pass at the method the array of dictionaries and I check if the entity exist or not. It work fine and I have not particulars problems. The 'problem', if it's the way to call it, is that I have 12000 element and this method run for about 53 seconds. It's very very slow. What type of solution can I adopt to make it more quick? Or I should just put this method inside a background process? thanks
Should you put it in a background process?
Absolutely. Start a background thread and create a child context from your main context to do all the work in.
What else can be done
Every unsaved change you make to a managed object context is stored in memory. Making thousands of changes before saving is inadvisable as it will take a lot of memory but also the save take will take a long time.
You could batch the updates into say 100 changes at a time and save each block of 100.
Alternatives
If you are always loading in these items for the app then you could also preload them into a DB and bundle it into the app itself.
That way you don't need to save them at run time as they are already in there.