I'am currently migrating an iphone application using SQLite to CoreData.
I need to do an INSERT or REPLACE to add only the new content, is there a way to do this or do I have to fetch all the DB and look for existing objects and add the new ones ?
Thanks.
Remember, Core Data is an object hierarchy that happens to persist to a DB so you need to look at it like an object graph and not a database.
Therefore, yes you need to check to see if the object exists already using some defined unique ID and if it does not currently exist you need to create the new object vs. updating the existing object.
You don't need to fetch all of the objects, search the store using a NSFetchRequest
and a NSPredicate
to check for existence; if it exists update, if it doesn't create it.
Basically we order the inserted(fetched) data and the json data so at every index, they have equal values. We then retrieve the value at the respective index and update the managed object and in the case the counter is larger than the fetched results length, we insert a new managed object.
//Add JSON objects into entity
- (void) insertUpdate:(NSArray *)jsonArrayData {
//sort JSON Data
NSSortDescriptor *idDescriptor = [[NSSortDescriptor alloc] initWithKey:@"entityID" ascending:YES selector:@selector(localizedStandardCompare:)];
NSArray *sortDescriptors = @[idDescriptor];
NSArray *sortedJSONArray = [jsonArrayData sortedArrayUsingDescriptors:sortDescriptors];
//get entity
NSEntityDescription *entity = [NSEntityDescription entityForName:@"entity" inManagedObjectContext:self.managedObjectContext];
// Get the ids from json in sorted order.
NSMutableArray *entityIDs = [[NSMutableArray alloc]init];
for (NSDictionary *jsonValues in jsonArrayData) {
id value = [jsonValues objectForKey:@"entityID"];
[entityIDs addObject:value];
}
//sort to make sure json and fetched data are both sorted in same manner
[entityIDs sortUsingSelector:@selector(compare:)];
// create the fetch request to get all Entities matching the IDs
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
NSString *filter = @"(%K IN %@)";
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: filter, @"entityID", entityIDs]];
// Make sure the results are sorted as well.
[fetchRequest setSortDescriptors:
@[ [[NSSortDescriptor alloc] initWithKey: idName ascending:YES] ]];
// Execute the fetch.
NSError *fetchError;
NSArray *entityMatchingNames = [self.elRehabCoreData.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];
int i = 0;
//loop over JSONData
for (NSDictionary *keyedValues in sortedJSONArray) {
id value = [keyedValues objectForKey:@"entityID";
//Create NSManagedObject
NSManagedObject *managedObject = nil;
int updateInsert = 0;
if(entityMatchingNames.count > i ){
//update
managedObject = [entityMatchingNames objectAtIndex:i];
if ([[managedObject valueForKey:@"entityID"] isEqual:[keyedValues valueForKey:@"entityID"]]){
updateInsert = 1;
}
}else{
//insert
managedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];
updateInsert = 1;
}
i++;
//set value if updateInsert is true
// The updateInsert flag is an extra security to make sure we only update when the value in JSON data is equal that of fetched data
if (updateInsert) {
[managedObject setValue:value forKey:attribute];
}
}
//save core data stack
[self saveContext];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With