views:

663

answers:

1

Let me start off by saying Im VERY new to iphone development, but Im trying really hard to learn, so any help any of you professionals out there are willing to share is greatly appreciated! So I have a question that would be SO awesome if someone could answer for me. I am studying up more one core data and have been using the core data books example from the apple developer website found here. It is a pretty straight forward application, but I am trying to change something and I can't figure out how to do it and it is driving me CRAZY!!! Natively, the app shows the author in the tableview section heading, with the title in the cell. I would like to change that and set the copyright date (one of the attributes of the book) as the section header. Right now, I can get it to show, but it shows the date in this format:

2009-12-01 10:11:31 -0700

But thats not the right format, Id like to use this format:

Tuesday December 1

Probably using this code:

NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];

[outputFormatter setDateFormat:@"EEEE MMMM d"];

NSString *date = [outputFormatter stringFromDate:[NSDate date]];

but the problem is that the date value is coming in from the datepicker, and I can't figure out (with all this crazy 'key' business) how to format the date value that came from the picker and put it onto the section header. If you have any time to possibly follow the link to the apple wbsite above and poke around until you can answer my dilema, IT WOULD BE SO APPRECIATED!!!! Thank you.

Okay so here is my code I put in the save method:

 // Pass current value to the edited object, then pop.
if (editingDate) {
    NSString *rawDate = (NSString *)datePicker.date;
 NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
 [outputFormatter setDateFormat:@"yyyy-MM-dd"];
 NSDate *date = (NSDate *)[outputFormatter dateFromString:rawDate]; 

 [outputFormatter setDateFormat:@"EEEE MMMM d"];
 NSString *formattedDateStr = (NSString *)[outputFormatter stringFromDate:date];

 [editedObject setValue:(NSDate *)formattedDateStr forKey:editedFieldKey];
}

And then for whatever reason, the date just wont save in the app, and the compiler throws this error:

The Debugger has exited with status 0. [Session started at 2009-12-02 09:51:26 -0700.] 2009-12-02 09:51:47.342 CoreDataBooks[17981:20b] * -[__NSCFDate length]: unrecognized selector sent to instance 0x3e79850 2009-12-02 09:51:47.343 CoreDataBooks[17981:20b] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSCFDate length]: unrecognized selector sent to instance 0x3e79850'

Probably just a quick fix, I am hoping I was at least in the right hemisphere as far as the code goes, thanks again for any help or insight you have time to offer.

+1  A: 

You don't have to worry about the key business at least to change the date format here. The copyright property in the book object is automatically changed using the key-business in the EditingViewController.

So you only have to change the place where that property is displayed. In DetailViewController.m, change this method:

- (NSDateFormatter *)dateFormatter {    
if (dateFormatter == nil) {
 dateFormatter = [[NSDateFormatter alloc] init];
 [dateFormatter setDateStyle:NSDateFormatterMediumStyle];  //REMOVE
 [dateFormatter setTimeStyle:NSDateFormatterNoStyle];  //REMOVE
}
return dateFormatter;

}

To this:

- (NSDateFormatter *)dateFormatter {    
if (dateFormatter == nil) {
 dateFormatter = [[NSDateFormatter alloc] init];
 [dateFormatter setDateFormat:@"EEEE MMMM d"];  //NEW LINE
}
return dateFormatter;

}

Edit: Forgot to mention that the actual display is done in cellForRowAtIndexPath in the same file. But that display code uses a class-level variable dateFormatter so we just modify its initialization.

Edit #2: You modified the sample code to group the rows by the book copyright date. To modify the date format in the section heading there is probably a more elegant way to do it but here is a crude solution. Modify titleForHeaderInSection in RootViewController.m to this:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *rawDateStr = [[[fetchedResultsController sections] objectAtIndex:section] name];

//convert default date string to NSDate...
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss ZZ"];
NSDate *date = [formatter dateFromString:rawDateStr];

//convert NSDate to format we want...
[formatter setDateFormat:@"EEEE MMMM d"];
NSString *formattedDateStr = [formatter stringFromDate:date];

return formattedDateStr;

}

The change above assumes you will only do sections by date. If not, you'll need to check whether the current grouping is by date otherwise it will try to convert author's name or title to a date and crash. You may also want to add a check for null/invalid date.

Edit #3: The copyright field is NSDate which contains both date and time. To group by date only, when the copyright field is edited, set the time part to 00 as follows (in save method in EditingViewController.m):

    // Pass current value to the edited object, then pop.
if (editingDate) {
 NSDate *pickedDateTime = datePicker.date;

 NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
 [formatter setDateFormat:@"yyyy-MM-dd 00:00:00 -0000"];
 NSString *pickedDateStr = [formatter stringFromDate:pickedDateTime];
 pickedDateTime = [formatter dateFromString:pickedDateStr];

    [editedObject setValue:pickedDateTime forKey:editedFieldKey];
}

HOWEVER, since the sample data provided in the example from Apple already includes time in the copyright field, editing or adding one book will not put it in the same group as another group with the same date because the other book still has the time portion in it. If you edit both books and save, it will clear the time in both and they will show in the same group.

A better solution would be to somehow tell the SortDescriptor to only look at the date portion of copyright only instead of the copyright as-is but I'm not sure how to do this yet.

DyingCactus
Hey thank you do much for your answer. I changed that bit of code, and it worked in that it changed the format of the date displayed right after you leave the date picker, while still in the book properties view, but once you save from there, it still showed the same annoying format in the sectionheader. It very well could be that the way I got the date to show up in the header was wrong to begin with, and that could be why its not working. What is the best way to set that up correctly? Any help you have to offer here would again be very appreciated. Thanks so much for your time.
Steve
There's probably a more elegant way to modify the section heading text when using a NSFetchedResultsController but I will add the crude solution to the main answer text shortly.
DyingCactus
SUCCESS!!! DyingCactus, I can't thank you enough! You rock. It works perfectly.
Steve
Ok, I am back. I am terribly sorry if I have gotten really annoying, but two issues have surfaced that weren't immediately apparent. When I save the copyright date, inside the book attribute screen, the date shows correctly, but when it saves outside in the uitableview, it shows the correct day number, but not the month. No matter which month you selected, it shows that its January. Pretty strange. And then the second issue is that in the native app, if there were two books by the same author, author was a static value, so it could compare and if the new books author matched one already in
Steve
existence, then it automatically put the new book under that author. I am tweaking and adjusting the purpose of the app a bit, and it would be ideal if the date value was static as well, meaning the value didn't have ever changing time values that were compared. Because right now as it sits, I can make like however many different dates the same in the datepicker, and they all come up seperate in the section header, and I think it is because inside the date is also the time which is always changing...If you have any insights on this issue, again it is greatly appreciated! Thanks so much
Steve
PS I promise this is the last time I'll bother you :) If I can just get this last bit squared away, I will be good to go. Thanks again.
Steve
Regarding always showing January: fix the date format from "yyyy-MM-DD HH:mm:ss ZZ" to "yyyy-MM-dd HH:mm:ss ZZ" (lowercase dd). I fixed the answer text as well.
DyingCactus
For date formatting strings, see http://unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns.
DyingCactus
Regarding the date grouping which currently includes time: in EditingViewController.m, in the save method, it currently takes the date as-is from the datepicker. Modify that code to first copy the datepicker's date to a local variable and blank out the time in there and use that value in the setValue statement.
DyingCactus
If this has resolved your original question, please mark this as the answer. Thanks.
DyingCactus
Well I gave it my best shot, but alas, nothing ever works out for me...I edited my original post, with the code that I came up with to do what you suggested I do in the save method, and then also I am including the compiler error. Again, very sorry for being annoying, but what may take you two minutes to figure, has taken me 3 hours to get wrong :) Thanks
Steve
I've edited the answer with the code for the save method but please note the HOWEVER part.
DyingCactus
Controlling cell height is a separate question so it's better to ask it separately. The site is question-centered. Cell height is also not necessarily specific to your project so many people (most more knowledgeable than myself) will be able to answer it. A helpful thing is to isolate the problem in a small application of your own (the Apple sample projects can be difficult to understand for newcomers), show what you've tried and be specific in your question. Thanks.
DyingCactus
Ok, that sounds great. I'll get going on it and post any legitimate road block that I just can't seem to figure out as a question on this site and get through it. Thanks for all of your help.
Steve