I have a simple two-tabbed table view controller. The user presses the plus button and is taken modally to another view controller to add text into textfields and select a date from the UIDatePicker.
Everything is working well, except for a duplication problem with Core Data and my dates.
In the app, the first table view displays occasions based on the entry added to the text fields but I have put in some code to check that the occasion doesn't already exist before creating it. What this means is if you have "Wedding" as an occasion and you save, if you enter another entry with "Wedding" as the occasion, rather than creating two cells in the table view with Wedding, it creates just one and when you click on it, it goes another view controller to display all entries for Wedding.
That is working well.
However when it comes to the UIDatePicker and selecting dates, duplicated items are being created.
The model is:
Transaction Entity Occasion Entity Date Entity
The transaction Entity has a relationship to the Occasion and Date Entity.
Let's look at some code:
The save method in the modal view controller:
- (IBAction)save:(id)sender
{
NSManagedObjectContext *context = [self managedObjectContext];
Transaction *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
Occasion *enteredOccasion = (Occasion *)[Occasion occasionWithTitle:self.occasionTextField.text inManagedObjectContext:context];
transaction.occasion = enteredOccasion;
// Code to save the date as well - shown below
}
That is calling the occasionWithTitle method which does the NSFetchRequest check:
+ (Occasion *)occasionWithTitle:(NSString *)title inManagedObjectContext:(NSManagedObjectContext *)context
{
Occasion *occasion = nil;
// Creating a fetch request to check whether the occasion already exists
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Occasion"];
request.predicate = [NSPredicate predicateWithFormat:@"title = %@", title];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *occasions = [context executeFetchRequest:request error:&error];
if (!occasions)
{
// Handle Error
}
else if (![occasions count])
{
// If the occasions count is 0 then let's create it
occasion = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context];
occasion.title = title;
}
else
{
// If the object exists, just return the last object .
occasion = [occasions lastObject];
}
return occasion;
}
The code for the date picker, also in the save method is:
Date *date = (Date *)[Date occasionWithDate:self.datePicker.date inManagedObjectContext:context];
transaction.dates = date;
Which calls:
+ (Date *)occasionWithDate:(NSDate *)enteredDate inManagedObjectContext:(NSManagedObjectContext *)context
{
Date *date = nil;
// Creating a fetch request to check whether the date already exists
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Date"];
request.predicate = [NSPredicate predicateWithFormat:@"dateOfEvent = %@", enteredDate];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"dateOfEvent" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *dates = [context executeFetchRequest:request error:&error];
if (!dates)
{
// Handle Error
}
else if (![dates count])
{
// If the dates count is 0 then let's create it
date = [NSEntityDescription insertNewObjectForEntityForName:@"Date" inManagedObjectContext:context];
date.dateOfEvent = enteredDate;
}
else
{
// If the object exists, just return the last object .
date = [dates lastObject];
}
return date;
}
To me, the code looks the same but of course one is passing a NSString and one is passing a selected NSDate from a UIDatePicker.
The result is when it comes to the second tabbed table view (for dates), if I create a new Transaction with 2 December 2013 as the date, and then create another entry on 2 December 2013, it creates two separate cells in the table view for the same date, which of course is not right.
Any help on this maddening issue would be very appreciated!
EDIT: On a related note, I am taking the Date selected from the DatePicker and having that displayed as the Section title of the TableView with specific formatting. I am doing that using this code:
-(NSString *)sectionDateFormatter
{
return [NSDateFormatter localizedStringFromDate:self.dates.dateOfEvent
dateStyle:NSDateFormatterLongStyle
timeStyle:NSDateFormatterNoStyle];
}
And calling this in the sectionNameKeyPath.