Objective C - can't set value in one method and access it from another - objective-c

I am trying to do the following:
1) user clicks button start, it runs startTimer method, which sets a new [NSDate date].
2) user clicks button stop it runs stopTimer method, which retrieves the [NSDate date] value.
I can't get step number 2 working. I've set it in the .h file. If I copy the code from the start method into the stop method it works. So, I can set the [NSDate date]. But, this is not what I want. I want to be able to set it in the startTimer method. How do i go about this?
.h file
#interface StartTest : UIViewController {
IBOutlet UILabel *timer;
NSDate *startNSDate;
NSDate *start;
}
- (IBAction)startTimer;
- (IBAction)stopTimer;
- (NSDate *)setStart;
- (NSDate *)getStart;
#end
.m file:
#implementation Ash
- (IBAction)startTimer {
startNSDate = [NSDate date];
}
- (IBAction)stopTimer{
start = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy"];
NSString *stringFromDate = [formatter stringFromDate:startNSDate]; // <<< this is where it fails
NSLog(#"stringfromdate: %#", stringFromDate);
}

startNSDate isn't retained and by the time you want to access it, it's already dealloc'd, hence you're trying to access garbage pointer
easiest solution for you will be
#interface StartTest : UIViewController {
IBOutlet UILabel *timer;
NSDate *startNSDate;
NSDate *start;
}
#property (nonatomic, strong) NSDate* startNSDate;
- (IBAction)startTimer;
- (IBAction)stopTimer;
- (NSDate *)setStart;
- (NSDate *)getStart;
#end
#implementation Ash
- (IBAction)startTimer {
self.startNSDate = [NSDate date];
}
- (IBAction)stopTimer{
start = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy"];
// this is where it fails, the reason being that startNSDate isn't retained
// and by this line, it's already dealloc'd, hence you're trying to access
// garbage pointer
NSString *stringFromDate = [formatter self.startNSDate];
NSLog(#"stringfromdate: %#", stringFromDate);
}
- (void)dealloc
{
self.startNSDate = nil;
[super dealloc];
}

Related

Property not found on object of type error

I am trying to access a class method from another class but I am getting error. I have a class 'Constants' in which I have written a class method 'changeDateFormat' and accessing it from some viewController.
Here is my code.
Constants.h
#interface Constants : NSObject
+(NSString *)changeDateFormat:(NSString *)currentDate;
#end
Constans.m
#implementation Constants
+(NSString *)changeDateFormat: (NSString *) currentDate
{
NSString *convertedDate = #"";
#try
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM dd yyyy"];
NSDate *date = [dateFormatter dateFromString:currentDate];
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc]init];
[dateFormatter1 setDateFormat:#"yyyy-mm-dd"];
convertedDate = [dateFormatter1 stringFromDate:date];
}
#catch(NSException *e)
{
NSLog(#"%# %#", e.name, e.reason);
}
return convertedDate;
}
#end
I am trying to access the above method like Constants.changeDateFormat:#"Mar 11 2018" but I am getting error - Property not found on object of type.
You are sending the changeDateFormat: method. You don't use a . for that. This is the correct syntax:
NSString *output = [Constants changeDateFormat:input];

Working with Date and Time separately using NSDatePickerView on Xcode

I have a part of app that set date and time of an appointment. For this, I have two NSDatePickerView. The first one I set to NSDatePickerModeDate, while the other one to NSDatePickerModeTime. But actually they should be referring to a same NSDate object inside a NSMutableDictionary entry. I know about NSDatePickerModeDateTime, but I need the date and time to be picked separatedly.
I know how to set up the NSDatePickerView to show and hide and event control and such, but at the event control UIControlEventValueChanged fire for NSDatePickerView, I'm confused on how to code the change for this, and also how to initialise the pickers (datePicker.date = today, timePicker.date = "9:00 AM")
#interface MyViewController () {
NSMutableDictionary *data;
}
#end
#implementation MyViewController
#synthesize datePicker, timePicker;
- (void) viewDidLoad {
[super viewDidLoad];
data = [[NSMutableDictionary alloc] init];
[data setObject:[NSDate date] forKey:#"date"];
datePicker.datePickerMode = UIDatePickerModeDate;
timePicker.datePickerMode = UIDatePickerModeTime;
[datePicker addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged];
[timePicker addTarget:self action:#selector(changeTime:) forControlEvents:UIControlEventValueChanged];
datePicker.date = data[#"date"]; //????
timePicker.date = data[#"date"]; //????
}
- (IBAction) changeDate:(id)sender {
UIDatePickerView *dp = (UIDatePickerView *)sender;
[data setObject:dp.date forKey:#"date"]; //????
}
- (IBAction) changeTime:(id)sender {
UIDatePickerView *tp = (UIDatePickerView *)sender;
[data setObject:tp.date forKey:#"date"]; //????
}
The part that I don't know how to code it is denoted by //????. I've read about NSDateFormatter, NSCalendar, and some kind of date components on some answers, but that was actually making me more confused as it also throws strings and structs into the mix, what to use to do what and when. Please help.
You can set both date pickers to the same date and time. The unused part is there but it isn't displayed and can't be changed. When the user changes the value of one date picker you have to set the other date picker to the same value.
- (IBAction)changeDate:(id)sender {
NSDatePicker *dp = (NSDatePicker *)sender;
[data setObject:dp.dateValue forKey:#"date"];
self.timePicker.dateValue = dp.dateValue;
}
- (IBAction)changeTime:(id)sender {
NSDatePicker *tp = (NSDatePicker *)sender;
[data setObject:tp.dateValue forKey:#"date"];
self.datePicker.dateValue = tp.dateValue;
}
u can try this
///Convert Full date to only date
- (IBAction) changeDate:(UIDatePickerView *)sender {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
NSString *dateStr = [dateFormatter stringFromDate:[sender date]];
[data setObject:dateStr forKey:#"date"];
}
///convert Date to only time format
- (IBAction) changeTime:(UIDatePickerView *)sender {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm a"];
NSString *dateStr = [dateFormatter stringFromDate:[sender date]];
[data setObject:dateStr forKey:#"Time"];
}

Segmentation Error In Objective C

I am trying to write a program for NSDate in ubuntu (as I don't have mac so I am using Ubuntu to run my objective c programs).
While compiling the program I am getting an error "Segmentation fault (core dumped)".
Below is my code
#import <Foundation/Foundation.h>
#import <objc/objc.h>
#import <objc/Object.h>
int main()
{
NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];
NSDate *now = [NSDate date];
NSLog(#"now %#", now);
NSTimeInterval secondsInAWeek = 7 * 24 * 60 * 60;
NSLog(#"secondsInAWeek %#", secondsInAWeek);
NSDate *lastWeek = [NSDate dateWithTimeInterval: secondsInAWeek
sinceDate:now];
NSLog(#"last week %#", lastWeek);
NSDate *nextWeek = [NSDate dateWithTimeInterval: secondsInAWeek
sinceDate:now];
NSLog(#"next week %#", nextWeek);
[pool drain];
return 0;
}
Please help me to find the error. I am able to get the output for NSDate *now, but after that i am getting the segmentation error.
Ask me if you need any more info regarding the code.
I guess I am able to get a solution to my answer. I was trying different things and this solution worked but still I don't know how it did.
#import <Foundation/Foundation.h>
#import <objc/objc.h>
#import <objc/Object.h>
int main()
{
NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];
NSDate *now = [NSDate date];
NSLog(#"now %#", now);
NSTimeInterval secondsInAWeek = 7 * 24 * 60 * 60;
NSLog(#"secondsInAWeek %f", secondsInAWeek);
NSDate* lastWeek = [[[NSDate alloc] initWithTimeInterval:-secondsInAWeek sinceDate:now] autorelease];
NSLog(#"last week %#", lastWeek);
NSDate *nextWeek = [[[NSDate alloc] initWithTimeInterval:secondsInAWeek sinceDate:now] autorelease];
NSLog(#"next week %#", nextWeek);
[pool drain];
return 0;
}
I have changed
NSDate *lastWeek = [NSDate dateWithTimeInterval: secondsInAWeek
sinceDate:now];
with
NSDate *lastWeek = [[[NSDate alloc]
initWithTimeInterval:secondsInAWeek sinceDate:now] autorelease];
Its working fine and giving the desired output.
I still don't know why and how it worked. :)

Filtering json data and reloading the resulted data into myTableView

Im trying to load an events(data) (from json file) that matches today's date into my tableView when the today's button is pressed then only the data with today's date will be loaded there and when the future button is pressed the events with later dates will be loaded, the only problem I have here is when i run my program nothing is actually happening when I press in either of these UIbuttons, I got all the events regardless their date and without even clicking on any UIButton, u can see below some of my code, it would be great if someone could figure out what is the problem there and since Im not quiet sure about how to use predicate to filter the data:
#property (strong, nonatomic) NSArray *dateEvents;
#end
#implementation HomeViewController {
NSArray *_events;
NSArray *_dateEvents;
}
- (IBAction)upcomingEvents:(id)sender {
NSDate *currDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"dd-MM-YYYY"];
NSString *dateString = [dateFormatter stringFromDate:currDate];
NSLog(#"mama");
_dateEvents = [_events filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(Events * event, NSDictionary *bindings){
return [event.date isEqualToString:dateString];
}]];
self.myTableView.dataSource = self;
[self.myTableView reloadData];
NSLog(#"yes");
}
Thanks,
I'm not sure this will definitely help, because I can't see enough code so be certain that this is your problem, but you might find it useful to convert all the dates to NSDate objects (so that you can be certain that the problem is NOT that the strings are actually not equal), and then check whether the day is the current day, or not, by using this category method on NSDate:
NSDate+Extensions.m:
static NSCalendar* ___calendar;
#implementation NSDate (Extensions)
- (BOOL)isSameDay:(NSDate*)date
{
NSCalendar* calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:self];
return [comp1 day] == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year] == [comp2 year];
}
-(NSCalendar*)currentCalendar
{
if(___calendar == nil)
{
___calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
}
return ___calendar;
}
#end
NSDate+Extensions.h
#interface NSDate (Extensions)
- (BOOL)isSameDay:(NSDate*)date;
#end

How can I make a Date to jump every n seconds?

I want to make the date to change one day every "n" seconds, like a time machine. I have this code but nothing happens, any help will be appreciated.
this is the code: no issues, no error ... no tomorrow date!
-(IBAction)jumpDate
{
NSDateFormatter *dateFormater = [[NSDateFormatter alloc]init];
[dateFormater setDateFormat:#"dd MMMM yyyy h:mm:ss"]; //dateFormater.dateStyle =NSDateFormatterLongStyle; //USA date style MMMM-dd-yyyy
[dateFormater setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"CDT"]];
NSDate *todayDate = [[NSDate alloc]init];
[gregDate setText : [dateFormater stringFromDate:todayDate]];
[NSString stringWithFormat:#"dd MMMM yyyy", dayCount];
dayCount++;
if (dayCount >= 365)
{
dayCount = 365;
[timerDate invalidate];
}
}
//and the timer
- (void)viewDidLoad
{
NSDateFormatter *dateFormater = [[[NSDateFormatter alloc]init]autorelease];
[dateFormater setDateFormat:#"dd MMMM yyyy"];
NSTimeInterval secondsPerDay = 86400 ; // = 24 * 60 * 60
NSDate *today = [[[NSDate alloc]init]autorelease];
NSDate *tomorrow;
tomorrow = [today dateByAddingTimeInterval:(NSTimeInterval)secondsPerDay];
[gregDate setText : [NSString stringWithFormat:#" %# ",tomorrow]];
dayCount = 1;
timerDate=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(jumpDate)userInfo:nil repeats:YES];
[super viewDidLoad];
}
I have 3 questions, not all directly related to your question.
Why -(IBAction)jumpDate is an IBAction, if you are calling this method from your code you should changed it to (void) and if an IBAction need to call that, call it from an other method that would be the action for that button.
Is there a missing space in your code before userInfo in this call :
timerDate=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(jumpDate)userInfo:nil repeats:YES];
Did you verified that your IBOutlet are all set properly? I've stop counting the times I've forgot that.
[gregDate setText : [NSString stringWithFormat:#" %# ",tomorrow]];
What is gregDate? is it an IBOutlet pointing to a UILabel?
And you've probably verified this, but, that call retunr a valid string?
You should not call your IBAction method from your timer, for 2 reasons,
1. I really think it's bad design, it's introducing confusion on the role of this method since it's also call from a timer.
2. The method signature doesn't match the one NSTimer needs
aSelector:
The message to send to target when the timer fires. The selector must have the following signature:
- (void)timerFireMethod:(NSTimer*)theTimer
This text come from the NSTimer class reference.
Replace this line:
NSDate *todayDate = [[NSDate alloc]init];
with this line:
NSDate *todayDate = [[NSDate date] dateByAddingTimeInterval:dayCount * 86400];