I have been trying to add objects in core data. So, i want that it should not allow duplicate entries in core data store. How to do that? This is my code related to save data.
Let me put the best approach from Apple Sample code itself. Please refer the sample code "ThreadedCoreData" for more info.
https://developer.apple.com/library/content/samplecode/ThreadedCoreData/Introduction/Intro.html
// before adding the earthquake, first check if there's a duplicate in the backing store
NSError *error = nil;
Earthquake *earthquake = nil;
for (earthquake in earthquakes) {
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"location = %@ AND date = %@", earthquake.location, earthquake.date];
NSArray *fetchedItems = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedItems.count == 0) {
// we found no duplicate earthquakes, so insert this new one
[self.managedObjectContext insertObject:earthquake];
}
}
I think the best approach would be to call the countForFetchRequest method using a predicate to evaluate whether your store has a matching object. Since this type of request does not pull back any objects it should be more performant than other solutions. Here is a Swift 2.0 implementation added to a NSManagedObject subclass.
func tokenExists (aToken:String) -> Bool {
let request: NSFetchRequest = NSFetchRequest(entityName: self.className!)
let predicate = NSPredicate(format: "token == %@", argumentArray: [aToken])
request.predicate = predicate
let error: NSErrorPointer = nil
let count = self.managedObjectContext!.countForFetchRequest(request, error: error)
if count == NSNotFound {
return false
}
return true
}
NB - (One could substitute any equality criteria you like for the predicate but keep in mind that if possible you should use a numerical identifier if one is available ~ for best performance)
Usage:
One might then use the function above during the insertion:
func insertToken (value:String) {
if !tokenExists(value) {
self.token = value
saveState()
}
}
As there is no built in method available, you need to fetch results and check whether result contains object you don't want to be duplicated.
Here is code snippet:
-(void)checkForDuplicates
{
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Students"
inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"students"
ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
NSError *Fetcherror;
NSMutableArray *mutableFetchResults = [[managedObjectContext
executeFetchRequest:request error:&Fetcherror] mutableCopy];
if (!mutableFetchResults) {
// error handling code.
}
if ([[mutableFetchResults valueForKey:@"users"]
containsObject:name.text]) {
//notify duplicates
return;
}
else
{
//write your code to add data
}
}
Hope this may help you!
no, coredata has no built-in in uniquing as it isn't a DB.
you have to assure uniqueness in your program logic.
e.g. often, one does a fetch for an entry that should be unique and if that fetch has 1 entry, don't add another, else add it!
==> this works well for serial CD access, but can get complicated with multiple contexts that run in a multithreaded env
In Core Data there is no such thing as duplicate entries, as least as far as Core Data is concerned. Not in the sense of looking at it from a database point of view. Which makes sense because Core Data is not a database it is an object graph management system.
So to prevent duplicates you need to do a search first then if the search returns NULL
only then save, else do nothing.
This article gives you code which you can customise to your needs