Fastest way to check if an object exists in Core Data or not?
Yes, definitely there is a better method. Setup a fetch request as usual, but, instead of actually executing it, simply ask for the number of objects it would have returned if it had been passed to executeFetchRequest:error:
This can be done using
- (NSUInteger)countForFetchRequest:(NSFetchRequest *)request error:(NSError **)error;
Something like this:
- (int) numberOfContacts{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSManagedObjectContext *managedObjectContext = yourManagedObjectContext;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Contacts" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSError *error = nil;
NSUInteger count = [managedObjectContext countForFetchRequest:request error:&error];
[request release];
if (!error){
return count;
}
else
return -1;
}
Setup a Core Data request and, instead of actually issuing the query, do the following:
NSError *error = nil;
NSUInteger count = [managedObjectContext countForFetchRequest:request
error:&error];
if (!error) {
return count;
} else {
return 0;
}
In practice, the method countForFetchRequest:error:
returns the number of objects a given fetch request would have returned if it had been passed to executeFetchRequest:error:
.
Edit: (by Regexident)
As Josh Caswell correctly commented, the correct way to handle errors is either this:
if (count == NSNotFound) {
NSLog(@"Error: %@", error);
return 0;
}
return count;
or this (without error logging):
return (count != NSNotFound) ? count : 0;
Update to SWIFT 5:
func checkIfItemExist(id: Int, type: String) -> Bool {
let managedContext = CoreDataStack.sharedInstance.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "DetailsEntity")
fetchRequest.fetchLimit = 1
fetchRequest.predicate = NSPredicate(format: "id == %d" ,id)
fetchRequest.predicate = NSPredicate(format: "type == %@" ,type)
do {
let count = try managedContext.count(for: fetchRequest)
if count > 0 {
return true
}else {
return false
}
}catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
return false
}
}