Question

I have a working app right now but I have hit a big stumbling block. The app has the premise of a tab bar controller (TB) which has two Tabs consisting of one table view in each tab. Table view 1 (TV1) is populated by the user clicking the plus button in the navigation bar and filling in the name and event text fields and selecting a date from the date picker. Table view 2 is an illustration of each unique event that the user has created. Where table 1 shows every transaction in chronological order, table 2 shows only the unique event names so you can view the transactions by events.

I'm using Core Data and NSFetchedResultsControllers to tie everything together.

This is working very well but I'm looking to introduce an update.

If the user clicks on the Table 2 and sees the events showing for example, Anniversary, Birthday and Wedding, and then clicks on say, Birthday, they will see all of the transactions where event = birthday (selected events scene). I've put a new navigation bar button in here (selected events) to allow the user to add a new entry with the date and event already populated from the selected event.

I have this 95% working. The issue comes down to NSLocales and Date Formatters.

I'll put some code here and then talk about the issue:

In the Add Entry, the NSCalendar for the date and datePicker is:

    NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    // Will explain the commented out lines    
    //NSLocale *brLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
    //[cal setLocale:brLocale];
    NSDateComponents *components = [cal components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
                                          fromDate:self.datePicker.date];
    [components setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
    NSDate *selectedDate = [cal dateFromComponents:components];

Before this update, I did not have the locale (Commented out code) in this code because it would just use the device local and that worked very well. Now I had to add it in to get the next part working.

In the Selected Event Controller, the prepareForSegue is:

if ([segue.identifier isEqualToString:@"Create New Entry From Event"])
{
    AddEntryViewController *addEntryViewController = (AddEntryViewController *)segue.destinationViewController;
    [addEntryViewController setSelectedEvent:self.occasion.title];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0] ;
    NSString *sectionTitle = [self tableView:self.selectedOccasionTableView titleForHeaderInSection:indexPath.section];

    NSLog(@"The section header is: %@", sectionTitle);

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"MMMM d, yyyy"];
    NSDate *dateFromString = [[NSDate alloc] init];
    dateFromString = [dateFormatter dateFromString:sectionTitle];
    NSLog(@"The new date is %@", [dateFormatter stringFromDate:dateFromString]);
    [addEntryViewController setSelectedDate:dateFromString];
    [addEntryViewController setIsFromSelectedEvent:YES]; 
}

I'm getting the date from the section title and sending that over to the Add Entry where:

- (void)setSelectedDate:(NSDate *)selectedDate
{
    _selectedDate = selectedDate;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.occasionTextField.text = self.selectedEvent;

    if (self.isFromSelectedEvent)
    {
        NSLog(@"This gets run");
        [self.datePicker setDate:self.selectedDate animated:YES];
    }
}

The issue I'm having is - the app crashes if the device locale is set to anything but the US locale (with the code not commented out above). This is not desirable of course.

A LOT of effort has gone into getting the app working with the dates in this format and I cannot change that because a lot is dependent on the dates in the section headers.

I need a way to adjust the NSDateFormatter code in the prepareForSegue to take into account whatever format the device is using.

The code below is converting the NSDate into an NSString so it's readable in the section title, but here is where the problem is.

-(NSString *)sectionDateFormatter
{
    return [NSDateFormatter localizedStringFromDate:self.dates.dateOfEvent
                                          dateStyle:NSDateFormatterLongStyle
                                          timeStyle:NSDateFormatterNoStyle];
}

If the user is using an American locale, the date will appear as Month Date, Year. If the user is using a UK locale it'll be Date Month Year.

I need to somehow fix this. I either need to:

1) Set the locale of the NSDate/NSString to one particular format regardless of locale, or 2) Manipulate the code to support all potential locales.

Number 1 seems to be easier but I have no idea how to achieve this. I need this app to not crash if you're using it of course.

If you're using a UK locale, it crashes with:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: date'

I need a way to stick to one format regardless of where you are. For example, I would love to set the format to be "Date Month, Year" regardless of whether you're in America and using an American locale, or in Singapore using a Singaporean Locale.

Any thoughts in the right direction would be seriously appreciated here.

Was it helpful?

Solution

To control the date format in depend of the current locale setting define a formats instead of using the date/time style. For example if you use

[dateFormatter setDateFormat:@"MMMM dd, yyyy"]; 

Or any other format you want to display. The you can create the string object using this date formatter

[dateFormatter stringFromDate:self.dates.dateOfEvent];

Read up on various format strings here: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top