views:

34

answers:

2

I haven't seen any other questions quite like this on here, but I'm hoping someone has some insight. I'm just starting to learn Core Data.

Basically, I have two methods and I want to choose which one to call with an if/else statement based on whether or not the "Contacts" table contains any records. Is there a way using core data to check if there are any records in a table?

The best way I've found so far is to set the fetchLimit to 1 and then check to see if anything returns.

[request setFetchLimit:1];

But I keep thinking there has to be a better/easier way. Anyone know or have a good reference I can look at?

Thanks a ton!

+2  A: 

It's not necessarily any better or easier, but you can look for a specific record and then create it if it doesn't exist like this:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Contact" 
                            inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];

NSError *error;
// Filter based on a predicate
[fetchRequest setPredicate:
                [NSPredicate predicateWithFormat:@"identifier == %@", @"1"]];
NSManagedObject *contact = [[managedObjectContext 
                   executeFetchRequest:fetchRequest error:&error] lastObject];

// If the contact was not found
if (!contact)
{
  // Create the contact
  contact = [NSEntityDescription insertNewObjectForEntityForName:@"Contact" 
                                  inManagedObjectContext:managedObjectContext];
  [contact setValue:[NSNumber numberWithInt:1] forKey:@"identifier"];
  [managedObjectContext save:nil];
}

Marcus Zarra posted some code that demonstrates this in a feed reader app. Marcus is the Core Data master.

Matt Long
I don't have any specific record to search for as it could vary.
Gorgando
@Matt - In looking at your answer, it actually will help me out in another part of my code even though it doesn't solve my original question. I upvoted your answer and will accept it if nobody else has a better answer to my original question. Thanks!!
Gorgando
+3  A: 

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;

}
unforgiven
+1 good catch. That is one of those methods that is seldom used and people forget about.
TechZen
So is this method faster than asking it to return the first contact?
Gorgando
Yes doing a count is always going to be faster than a fetch (assuming the same predicate on both).
Marcus S. Zarra