Reputation: 292
I am working on a code example from NSScreenCast that deals with importing to a Core Data application (link). I have the example working for the most part. I am able to push the refresh button, it parses the json and imports it in to the database. However, every time I press the refresh button it re-adds the same data. I have traced it down to the following code.
+ (Brewery *)breweryWithServerId:(NSInteger)serverId usingManagedObjectContext:(NSManagedObjectContext *)moc {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[Brewery entityName]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId = %d", serverId]];
[fetchRequest setFetchLimit:1];
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:fetchRequest error:&error];
NSLog(@"results: %@", results);
if (error) {
NSLog(@"ERROR: %@ %@", [error localizedDescription], [error userInfo]);
exit(1);
}
if ([results count] == 0) {
return nil;
}
NSLog(@"results objectAtIndex:0 = %@", [results objectAtIndex:0]);
return [results objectAtIndex:0];
}
What happens is this method is that it tries to see if the item already exists in the database. If this call returns nil, then the code in MasterViewController adds it again to the database. I have done some debugging and the serverId does get passed. Also, the fetchrequest seems to be valid (haven't been able to debug it to be sure). As you can see I have put a NSLog for the results, but it returns an empty result. So, it then goes to if the results count is 0 which it is, it returns nil. Thus my issue. I don't see any where else where this issue could be a problem. Any thoughts?
Mike Riley
Upvotes: 3
Views: 4232
Reputation: 5122
I think there is a problem in your predicate. It should read:
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId == %d", serverId]];
You missed the double equals....
Found out it doesn't matter. You should check to make sure your moc
is not nil. Are you sure you're passing it in correctly?
Upvotes: 0
Reputation: 6058
You're trying to compare a scalar value (NSInteger
) with an object value (NSNumber
) in your predicate.
Try:
[NSPredicate predicateWithFormat:@"serverId = %@", [NSNumber numberWithInteger:serverId]]
Upvotes: 1
Reputation: 35161
I just modified your method, you can just take a try:
+ (Brewery *)breweryWithServerId:(NSInteger)serverId usingManagedObjectContext:(NSManagedObjectContext *)moc {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[Brewery entityName]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId == %d", serverId]];
[fetchRequest setFetchLimit:1];
NSError *error = nil;
// if there's no object fetched, return nil
if ([managedObjectContext countForFetchRequest:fetchRequest error:&error] == 0) {
NSLog(@"!!!WARN: NO Object Matches.");
return nil;
}
// fetch your object
Brewery *result = [[moc executeFetchRequest:fetchRequest error:&error] lastObject];
if (error != nil) {
NSLog(@"ERROR: %@ %@", [error localizedDescription], [error userInfo]);
return nil;
}
NSLog(@"results objectAtIndex:0 = %@", result);
return result;
}
Note: -countForFetchRequest:error:
is more efficient as it only 'returns the number of objects a given fetch request would have returned'. You can use this method to check whether there's a object that matches.
Upvotes: 4