NSDate value not accessible across methods - nsdate

Am sorry to ask such a trivial question. Am a newbie to Objective-C, & simply cannot see how to get this working, after having tried several possible ways & google'd around for it. Please help!
My question is simple. I have a class-level NSDate object, which is declared outside any method in the class as:
NSDate *fromDate;
Now, within a method, am setting this value to the date from a DatePicker as:
fromDate = [datePicker date];
Soon after the above assignment, I print its value into the log & it works fine.
NSLog(#"From Date: %#", fromDate);
Now, when I use NSDate's value in another/different method, the value's gone! Why is it not persisted across methods in the same class itself? What can I do for the value to be accessible across methods?
Thanks for your reply.
Hi Remy,
I didn't know Objective-C didn't have class-level variables! Thanks for pointing it out!
Yes, I've set the project (in Xcode) to do ARC (so, I believe that should take care).
Here is the code:
In ViewController.h
....
....
#property (nonatomic, retain) NSDate *historyFromDate;
#property (nonatomic, retain) NSDate *historyToDate;
....
....
-(IBAction) fromDateChosen: (id)sender;
-(void) fetchTheHistory;
In ViewController.m
...
...
#synthesize historyFromDate;
#synthesize historyToDate;
....
....
-(IBAction) fromDateChosen: (id)sender {
NSString *buttonTitle = #"I've chosen the 'FROM' date";
if ([[buttonDateChosen currentTitle] isEqualToString:buttonTitle]) {
NSLog(#"User has chosen the 'From' date");
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
// Get the chosen date value
NSDate *fromDate = [datePicker date];
historyFromDate = fromDate;
// Set the 'to' date label to reflect the user's choice
labelFromDate.text = [dateFormatter stringFromDate:historyFromDate];
NSLog(#"'From' Date Chosen:%#", historyFromDate);
//[dateFormatter stringFromDate:[datePicker date]]);
[self fetchTheMoodHistory];
}
}
...
...
...
-(void) fetchTheHistory {
NSLog(#"Calling fetchTheHistory for the period from %#", historyFromDate);
...
...
}
...
...
fromDateChosen gets called after the user chooses a date form a Date Picker object in the UI.
Within the method 'fromDateChosen', when I print the historyFromDate, the value is correct.
But, when I print it in fetchTheHistory method, the value shows the current date/time (not the one the user chose).

The date property of UIDatePicker is retained by that class, and will be accessible as long as the date picker itself is in scope and valid (not been released). You are storing this date value in a variable, but not retaining it yourself, so when the date picker goes out of scope you lose the value. As a quick fix, do this instead;
fromDate = [[datePicker date] retain];
Now, this is not the best approach, you really should be making the date a property of whatever class is using this information.

Try put the fromDate variable under class scope, e.g:
#implementation ViewController
{
NSDate *fromDate;
}

Related

What format is a Date in CoreData - Date or String?

I have a routine that compares when a record was last updated on a website with the same record saved in CoreData on an iPad. Here, obsLastUpdated is a field in CoreData set as type Date.
Reading the data from CoreData into an NSDate:
NSDate *iPadDate = [[self.recordDetails objectAtIndex:0] obsLastUpdated]; //gets the date from CoreData
I get this warning:
Incompatible pointer types initializing 'NSDate *' with an expression
of type 'NSString *'
It is just a warning however and everything still works. If I try and compare this NSDate iPadDate with another NSDate there are no errors and everything works. But I would like to get to the bottom of the warning.
If I read from CoreData as a string and convert to an NSDate I can't seem to get the formatting correct and the app crashes. I have tried:
NSString *iPadDateStr = [[self.recordDetails objectAtIndex:0] obsLastUpdated];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSDate *iPadDate = [dateFormat dateFromString: iPadDateStr];
I realise that CoreData does not store the date as an NSDate but how exactly is it stored and how do I get around the warning?
CoreData Entity:
UPDATE:
The error was in the class where obsLastUpdated was declared as an NSString. Changed to NSDate and all is well.
Simply define it as NSDate, not NSString:
MyEntity *entity = [self.recordDetails first];
NSDate *iPadDate = entity.obsLastUpdated;

How to Format NSDate in the Model Layer

I have a NSDate that I want to return as formatted like 10:00PM.
I have the date formatter working.
I'm wondering how I can make it so that whenever I fetch that date it comes back formatted as desired.
The NSDate in question in a daily start time for an activity that is store in an NSManagedObject
subclass.
#implementation Schedule
#dynamic repeat;
#dynamic start;
-(NSString*)amPMFormat
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"h:mm a"];
return [dateFormatter stringFromDate:self.start];
}
#end
I'm using a keypath to fill in a TableViewCell. The object bound to the cell is a Ritual which knows a Schedule. My thought was to call the method amPMFormat using the keypath and just return the formatted date as a string but that doesn't work. This code is a cell created using Sensible TableView. The cell has a STEP bound to it, STEP has a SCHEDULE, and SCHEDULE has a start property which is an NSDate that only has hours and minutes saved into it.
SCCustomCell *descrCell = [SCCustomCell cellWithText:nil objectBindingsString:#"1:schedule.start.amPMFormat;3:desc" nibName:#"RitualCell"];
You've munged the Model and the View parts of your program.
The date (self.start) is an instant in time. You can represent that date in any of a multitude of calendars, languages, locale-specific formats, and precision. It's still a single instant in time.
The formatter is a way to build a standard string representation of that instant. If you want the date formatted a particular way "whenever [you] fetch that date", you can use -awakeFromFetch: to populate a read-only property. Or perhaps a class method on Schedule, +formattedStringForDate:, which formats an NSDate appropriately and returns an NSString.
Your cryptic second snippet mentions "bindings". Are you using Cocoa Bindings and writing an OS X app? If so, you can put a date formatter on the NSTextField instance in your XIB.

Questions about categories

I want to do is produce a simple NSDate date in addition to would like
to add methods to add and subtract.
Date * myDate = [NSDate date]; // today
NSLog ("10 days after:%#", [myDate addToDays: 10]);
================= category ==================
#implementation NSDate (AddDate)
- (NSDate *)addToDays:addToDays{
NSDate *returnDate = [***HowGetmyDate*** dateByAddingTimeInterval:60*60*24*addToDays];
return returnDate;
}
how get (myDate)?
The base date need not necessarily today.
Just use self to get your date object.
Category is the extension of the original class, you can operate/implement it as the original one.
#implementation NSDate (AddDate)
- (NSDate *)addToDays:addToDays{
NSDate *returnDate = [self dateByAddingTimeInterval:60*60*24*addToDays];
return returnDate;
}

NSFetchedResultsController only sorting by 1st sort descriptor

I'm seeing an issue where the NSFetchedResultsController is only sorting by the first NSSortDescriptor in the sortDescriptors array when the data changes. It's really infuriating.
I'm using an NSFetchedResultsController to manage a tableview that is displaying a list of items. These items have an inherent order based on the number property, but a user can favorite an item. Favorited items are displayed at the top of the table view, sorted by the number property.
So, the model looks something like this:
#interface Thing : NSManagedObject
#property (nonatomic, retain) NSNumber *number;
#property (nonatomic, retain) NSNumber *favorite;
#end
#implementation Thing
#dynamic number;
#dynamic favorite;
#end
And I'm configuring my NSFetchedResultsController like so:
- (void)loadView {
...
//
// configure fetched results controller for the things table view
NSFetchRequest *fetchThings = [[NSFetchRequest alloc] init];
fetchChannels.entity = [NSEntityDescription entityForName:NSStringFromClass([Thing class])
inManagedObjectContext:[DataManager sharedInstance].managedObjectContext];
fetchThings.sortDescriptors = #[
[NSSortDescriptor sortDescriptorWithKey:#"favorite" ascending:NO],
[NSSortDescriptor sortDescriptorWithKey:#"number" ascending:YES] ];
_fetchController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchThings
managedObjectContext:[DataManager sharedInstance].managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
NSError *error = nil;
if (![_fetchController performFetch:&error]) {
NSLog(#"error performing fetch! %#", error.localizedDescription);
}
}
When the table is initially loaded, _fetchController correctly sorts the items, so you could end up with something like this:
- Thing: favorite = YES, number = 2
- Thing: favorite = YES, number = 3
- Thing: favorite = NO, number = 1
- Thing: favorite = NO, number = 4
But if you were to un-favorite Thing Number 2, it only sorts by the 1st sort descriptor, and the list looks like this:
- Thing: favorite = YES, number = 3
- Thing: favorite = NO, number = 2
- Thing: favorite = NO, number = 1
- Thing: favorite = NO, number = 4
Has anyone run into this issue or found a work around for it?
Update
It would appear that if I favorite everything, then unfavorite everything, the sorting works itself out. This leads me to believe this could be a faulting issue? Unfortunately, I'm not sure how to work around that, either.
OK, I figured it out, and it's my own fault.
Just because the field represents a BOOL doesn't mean it's actually a BOOL. The favorite field in the Thing model is actually an NSNumber, and as such, has 3 states, #(YES), #(NO), and nil. Once I made sure I was initializing the favorite field properly the sorting started working as expected again.

String value cannot assigned to a string variable in iphone?

In my application, I take a UITextField value and trim it and assign to a string Variable declared in an Appdelegate. It assigns to a appdelegate variable and works well, sometimes It does not assign to the appdelegate variable.(This value is used in another view,so declared in appdelegate). Plz help...
NSString *txtTemp=[NSString stringWithFormat:#"%#",[txtName.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
txtName.text=txtTemp;
[self appDelegate].customSearchQuery=[NSString stringWithFormat:#"%#",txtTemp];
NSLog(#"--appDelegate.customSearchQuery =%#",appDelegate.customSearchQuery);
This is most probably a memory management problem.
NSString creates an autoreleased object. You will have to retain it if you want to use it outside the method you showed above. The easiest thing is to delcare as
#property (nonatomic, retain) NSString *customSearchQuery;
in your Appdelegate.h. That should do the trick.
In the dealloc-method of the appdelegate, you'll need to release it - otherwise you leak the NSString; with the declaration above, you'll add
customSearchQuery = nil;

Resources