This code raises the “CoreData: error: (19) PRIMARY KEY must be unique” error.
The Day entity has only a when attribute which is an NSDate, and a to-many relationship called tasks. Why this error? If a Day with a specific date is already stored, I fetch it, otherwise I insert it. So, for each day object, there should be a different when attribute. I am not sure if this is the primary key though. How to solve this ? Thank you in advance.
NSMutableSet *occurrences = nil;
occurrences = ...
NSMutableOrderedSet *newSet = [NSMutableOrderedSet orderedSetWithCapacity:[occurrences count]];
for(NSDate *current in occurrences) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// try to find a corresponding Day entity whose when attribute is equal to the current occurrence
// if none is available, create it
Day * day = [[self getDayForDate:current inManagedObjectContext:moc] retain];
if(!day){
day = (Day *) [NSEntityDescription insertNewObjectForEntityForName:@"Day" inManagedObjectContext:moc];
}
day.when = current;
[day addTasksObject:aTask];
[newSet addObject:day];
[moc insertObject:day];
[moc processPendingChanges];
[day release];
[pool release];
}
- (Day *)getDayForDate:(NSDate *)aDate inManagedObjectContext:(NSManagedObjectContext *)moc
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Day" inManagedObjectContext:moc];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(when == %@)", aDate];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
[request release];
Day *theDay = nil;
if(array && [array count] == 1){
theDay = [array objectAtIndex:0];
}
return theDay;
}
I guess you don’t need to insert a new
Dayif you already have it (this is the case when day is not nil). In particular I’m referring to[moc insertObject:day].If you use
insertNewObjectForEntityForName, that method inserts the object for you when you save the moc. If you need to modify it (you have retrieved a non-nil day) modify it and save. In additon, I will doprocessPendingChangeswhen the loop finishes (just for performance reasons).Hope that helps.