Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to check if an object exists in Core Data or not?

I want to see if an object is persisted in Core Data or not. For example, I have Friends in Core Data, and I identify them by firstName. I can query core data to see if "George" is known. If the result set array contains more than zero objects, I know George is there. But Core Data loads the whole thing into memory, and I actually just want to know if George is stored or not.

How would I do it the most efficient way?

like image 235
dontWatchMyProfile Avatar asked Feb 12 '10 13:02

dontWatchMyProfile


4 Answers

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;
like image 103
Massimo Cafaro Avatar answered Sep 24 '22 05:09

Massimo Cafaro


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;

}
like image 31
shaikh Avatar answered Sep 23 '22 05:09

shaikh


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
    }
}
like image 9
JhonnyTawk Avatar answered Sep 21 '22 05:09

JhonnyTawk


If the goal is to check if the object exist the solution is to implement this method in your Friend Model:

-(BOOL)exist
{
    NSManagedObjectContext *managedObjectContext = yourManagedObjectContext;
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Friends" inManagedObjectContext:managedObjectContext];

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity];
    [request setFetchLimit:1];
    [request setPredicate:[NSPredicate predicateWithFormat:@"firstName == %@", self.firstName]];    

    NSError *error = nil;
    NSUInteger count = [managedObjectContext countForFetchRequest:request error:&error];

    if (count)
    {
        return YES;
    }
    else
    {
        return NO;
    }
}
like image 7
Damien Romito Avatar answered Sep 21 '22 05:09

Damien Romito