I use UNUserNotificationCenter for local notification. I want to fire a local notification on multiple days from present date and if user select repeat then every week on same day and same time notification fire which days are selected by user. So i use the below code.
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekOfYear|NSCalendarUnitWeekday fromDate:now];//get the required calendar units
if (components.weekday>4)
{
components.weekOfYear+=1;//if already passed monday, make it next monday
}
components.weekday = 4;//Wednesday
components.hour = 12;
NSDate *fireDate = [calendar dateFromComponents:components];
UNUserNotificationCenter *centerMonday;
UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init];
objNotificationContent.title = #"change time";
objNotificationContent.body = #"This is local notification message! Every Wednesday";
objNotificationContent.sound = [UNNotificationSound defaultSound];
/// 4. update application icon badge number
objNotificationContent.badge = #([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
NSDateComponents *triggerDate = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:fireDate];
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerDate repeats:YES];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:#"swami12"
content:objNotificationContent trigger:trigger];
/// 3. schedule localNotification
centerMonday = [UNUserNotificationCenter currentNotificationCenter];
centerMonday.delegate= self;
[centerMonday addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error)
{
if (!error)
{
NSLog(#"Local Notification succeeded");
}
else
{
NSLog(#"Local Notification failed");
}
}];
So here i set repeat yes but notification comes only once on selected day not repeat every week. Help, I stuck here from last three days.Thanks
I have application that remind patient about his/her appointment through button.
if the patient click the button, I want to fetch all events in the patient calendar to check if the appointment is already exist or not. if not exist, I will create event.
I know how to add events into calendar but the fetching is return zero count??
Below is my code:
//set start and end date
NSDate* startDate = [NSDate date];//start from today
NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow:[[NSDate distantFuture] timeIntervalSinceReferenceDate]];//no end
NSLog(#"S Date %#", startDate);
NSLog(#"E Date %#", endDate);
NSString *AppointmentTitle=#"Appointment in Hospital at Pediatric Clinic";
EKEventStore *store = [[EKEventStore alloc] init];
NSArray *calendarArray = [store calendars];
NSPredicate *fetchCalendarEvents = [store predicateForEventsWithStartDate:startDate endDate:endDate calendars:calendarArray];
NSArray *eventList = [store eventsMatchingPredicate:fetchCalendarEvents];
BOOL IsFound;
int EventsCount=eventList.count;
for(int i=0; i < EventsCount; i++)
{
NSLog(#"Event Title:%#", [[eventList objectAtIndex:i] title]);
if ([[[eventList objectAtIndex:i] title] isEqualToString:AppointmentTitle])//check title
{
IsFound=TRUE;
break;
}
else
{
IsFound=FALSE;
}
}
This code was working fine 2 months ago. Suddenly, when I come back to test it, it didn't work. Did I miss something? or Is there any mistake in my code?
I need your help plz..
Finaaaaaaaally I got the answer,
I think Apple did something in permission
(
In iOS 5, you are only allowed to access Events (EKEntityTypeEvent) in the Event Store, unlike in iOS 6, where you can access Reminders (EKEntityTypeReminder). But you need the below code to at least get granted 1 time.
) "Answered by WrightsCS"
Find the code below:-
EKEventStore *store = [[EKEventStore alloc] init];
// Get the appropriate calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
if ([store respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
/* iOS Settings > Privacy > Calendars > MY APP > ENABLE | DISABLE */
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if ( granted )
{
NSLog(#"User has granted permission!");
// Create the start date components
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day = -1;
NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents
toDate:[NSDate date]
options:0];
// Create the end date components
NSDateComponents *oneYearFromNowComponents = [[NSDateComponents alloc] init];
oneYearFromNowComponents.year = 1;
NSDate *oneYearFromNow = [calendar dateByAddingComponents:oneYearFromNowComponents
toDate:[NSDate date]
options:0];
// Create the predicate from the event store's instance method
NSPredicate *predicate = [store predicateForEventsWithStartDate:oneDayAgo
endDate:oneYearFromNow
calendars:nil];
// Fetch all events that match the predicate
NSArray *events = [store eventsMatchingPredicate:predicate];
NSLog(#"The content of array is%#",events);
}
else
{
NSLog(#"User has not granted permission!");
}
}];
}
Here is my situation: I am making a countdown app which works fine but does not appear to stop when I call [stopWatchTimer invalidate];, and I have no idea why. Here is my code:
- (IBAction)btnStartPressed:(id)sender {
//Start countdown with the time on the Date Picker.
timeLeft = [pkrTime countDownDuration];
[self currentCount];
lblTimer.text = time; //sets the label to the time set above
pkrTime.hidden = YES;
btnStart.hidden = YES;
btnStop.hidden = NO;
//Fire this timer every second.
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/1.0
target:self
selector:#selector(reduceTimeLeft:)
userInfo:nil
repeats:YES];
}
- (void)reduceTimeLeft:(NSTimer *)timer {
//Countown timeleft by a second each time this function is called
timeLeft--;
// Get the system calendar
NSCalendar *sysCalendar = [NSCalendar currentCalendar];
// Create the NSDates
NSDate *date1 = [[NSDate alloc] init];
NSDate *date2 = [[NSDate alloc] initWithTimeInterval:timeLeft sinceDate:date1];
// Get conversion to months, days, hours, minutes
unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *conversionInfo = [sysCalendar components:unitFlags fromDate:date1 toDate:date2 options:0];
int sec = [conversionInfo second];
int min = [conversionInfo minute];
int hour = [conversionInfo hour];
NSString *seconds = [NSString stringWithFormat:#"%d",sec];
NSString *minutes = [NSString stringWithFormat:#"%d",min];
if (sec <= 9)
seconds = [NSString stringWithFormat:#"0%d", sec];
if (min <= 9)
minutes = [NSString stringWithFormat:#"0%d", min];
if ([conversionInfo hour] == 0)
time = [NSString stringWithFormat:#"%#:%#", minutes, seconds];
else
time = [NSString stringWithFormat:#"%d:%#:%#", hour, minutes, seconds];
lblTimer.text = time; //sets the label to the time set above
NSLog(#"%d", timeLeft);
if (timeLeft == 0) {
[self timerDone];
[stopWatchTimer invalidate];
stopWatchTimer = nil;
}
}
-(void)timerDone {
pkrTime.hidden = NO;
btnStart.hidden = NO;
btnStop.hidden = YES;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Timer Done" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alert show];
[self playAlert];
}
Please let me know what the problem is... I cannot find a problem with my code anywhere!
In your btnStartPressed: method, you have nothing preventing a second NSTimer from being allocated and assigned to stopWatchTimer. If you press the button twice, you'll end up with two timers, but only one will ever be invalidated.
Add something like:
if (stopWatchTimer) return;
To the beginning of btnStartPressed:. If that doesn't fix the problem, then there isn't enough context to know for sure what is going on beyond conjecturing that timeLeft is zero?
What Nate said, but here is another explanation.
Imagine if you do this (where stopWatchTimer is a global or instance variable, doesn't matter):
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:....];
Now, do this:
stopWatchTimer = nil;
[stopWatchTimer invalidate];
The timer won't invalidate, but it'll still fire. stopWatchTimer is a reference to the object. It isn't the object itself. Thus, when you assign a second timer to stopWatchTimer, you are overwriting the reference to the first timer, but that timer is still going to fire!
I need to take a stored NSDate and reliably determine whether it falls within the current moment's hour, day or week. I seem to have hacked together a solution, but not having solved this problem before, am not entirely confident that it's a reliable one.
Will this survive user-set 12 vs 24 hour time? the date formatting guide indicates that this user setting can lead to some unanticipated date behavior: "In iOS, the user can override the default AM/PM versus 24-hour time setting. This may cause NSDateFormatter to rewrite the format string you set."
What about the basic code pattern for this problem? Does this code seem to reliably serve its purpose? I hate to post a "check my code" sort of question, but it's an unfamiliar-enough problem to me, and tricky enough to rigorously test, that it seemed justified. NSDateFormatter is also relatively new to me; another motivation for the question.
NOTE: The main source of my nervousness is that converting dates to strings and then doing a string compare seems an inherently fragile method of solving this problem. But it's the best I could come up with.
Quick reference: the dateFormats I used for each of the three cases were:
dateFormat = #"yyyyMMddHH"; // For "this hour" check
dateFormat = #"yyyyMMdd"; // For "today" check
dateFormat = #"yyyyww"; // For "this week" check
Thanks! Code Follows:
- (BOOL)didThisCycle {
// Case 1: hourly; Case 2: daily; Case 3: weekly
BOOL did = NO;
NSDate *now = [NSDate date];
NSDate *lastDid = [self.didDates lastObject];
if (![lastDid isKindOfClass:[NSDate class]]) { // Crash protection
return NO;
}
int type = [self.goalType intValue];
switch (type) {
case 1:
{
// If hourly check hour
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"yyyyMMddHH";
NSString *nowString = [formatter stringFromDate:now];
NSString *lastDidString = [formatter stringFromDate:lastDid];
if ([nowString isEqualToString:lastDidString]) {
did = YES;
} else {
did = NO;
}
break;
}
case 2:
{
// If daily check day
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"yyyyMMdd";
NSString *nowString = [formatter stringFromDate:now];
NSString *lastDidString = [formatter stringFromDate:lastDid];
if ([nowString isEqualToString:lastDidString]) {
did = YES;
} else {
did = NO;
}
break;
}
case 3:
{
// If weekly check week
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"yyyyww";
NSString *nowString = [formatter stringFromDate:now];
NSString *lastDidString = [formatter stringFromDate:lastDid];
if ([nowString isEqualToString:lastDidString]) {
did = YES;
} else {
did = NO;
}
break;
}
default:
{
did = NO;
break;
}
}
return did;
}
Use the NSDateComponents class, like so:
NSDate *someDate = // whatever
NSDate *now = [NSDate date];
NSDateComponents *thenComponents = [[NSCalendar currentCalendar] components:NSHourCalendarUnit|NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:someDate];
NSDateComponents *nowComponents = [[NSCalendar currentCalendar] components:NSHourCalendarUnit|NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:now];
if([thenComponents year] == [nowComponents year] && [thenComponents month] == [nowComponents month] && [thenComponents day] == [nowComponents day] && [thenComponents hour] == [nowComponents hour])
{
// hooray
}
Remove the “hour” component if you just want to check the day, or remove both that and “day” (and replace with NSWeekCalendarUnit and the -week method) to check the week.
I have two dates: 2009-05-11 and the current date. I want to check whether the given date is the current date or not. How is this possible.
Cocoa has couple of methods for this:
in NSDate
– isEqualToDate:
– earlierDate:
– laterDate:
– compare:
When you use - (NSComparisonResult)compare:(NSDate *)anotherDate ,you get back one of these:
The receiver and anotherDate are exactly equal to each other, NSOrderedSame
The receiver is later in time than anotherDate, NSOrderedDescending
The receiver is earlier in time than anotherDate, NSOrderedAscending.
example:
NSDate * now = [NSDate date];
NSDate * mile = [[NSDate alloc] initWithString:#"2001-03-24 10:45:32 +0600"];
NSComparisonResult result = [now compare:mile];
NSLog(#"%#", now);
NSLog(#"%#", mile);
switch (result)
{
case NSOrderedAscending: NSLog(#"%# is in future from %#", mile, now); break;
case NSOrderedDescending: NSLog(#"%# is in past from %#", mile, now); break;
case NSOrderedSame: NSLog(#"%# is the same as %#", mile, now); break;
default: NSLog(#"erorr dates %#, %#", mile, now); break;
}
[mile release];
Here buddy. This function will match your date with any specific date and will be able to tell whether they match or not. You can also modify the components to match your requirements.
- (BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 {
NSCalendar* calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];
return [comp1 day] == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year] == [comp2 year];}
Regards,
Naveed Butt
NSDate *today = [NSDate date]; // it will give you current date
NSDate *newDate = [NSDate dateWithString:#"xxxxxx"]; // your date
NSComparisonResult result;
//has three possible values: NSOrderedSame,NSOrderedDescending, NSOrderedAscending
result = [today compare:newDate]; // comparing two dates
if(result==NSOrderedAscending)
NSLog(#"today is less");
else if(result==NSOrderedDescending)
NSLog(#"newDate is less");
else
NSLog(#"Both dates are same");
There are other ways that you may use to compare an NSDate objects. Each of the
methods will be more efficient at certain tasks. I have chosen the compare method
because it will handle most of your basic date comparison needs.
This category offers a neat way to compare NSDates:
#import <Foundation/Foundation.h>
#interface NSDate (Compare)
-(BOOL) isLaterThanOrEqualTo:(NSDate*)date;
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date;
-(BOOL) isLaterThan:(NSDate*)date;
-(BOOL) isEarlierThan:(NSDate*)date;
//- (BOOL)isEqualToDate:(NSDate *)date; already part of the NSDate API
#end
And the implementation:
#import "NSDate+Compare.h"
#implementation NSDate (Compare)
-(BOOL) isLaterThanOrEqualTo:(NSDate*)date {
return !([self compare:date] == NSOrderedAscending);
}
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date {
return !([self compare:date] == NSOrderedDescending);
}
-(BOOL) isLaterThan:(NSDate*)date {
return ([self compare:date] == NSOrderedDescending);
}
-(BOOL) isEarlierThan:(NSDate*)date {
return ([self compare:date] == NSOrderedAscending);
}
#end
Simple to use:
if([aDateYouWantToCompare isEarlierThanOrEqualTo:[NSDate date]]) // [NSDate date] is now
{
// do your thing ...
}
If you make both dates NSDates you can use NSDate's compare: method:
NSComparisonResult result = [Date2 compare:Date1];
if(result==NSOrderedAscending)
NSLog(#"Date1 is in the future");
else if(result==NSOrderedDescending)
NSLog(#"Date1 is in the past");
else
NSLog(#"Both dates are the same");
You can take a look at the docs here.
By this method also you can compare two dates
NSDate * dateOne = [NSDate date];
NSDate * dateTwo = [NSDate date];
if([dateOne compare:dateTwo] == NSOrderedAscending)
{
}
The best way I found was to check the difference between the given date and today:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* now = [NSDate date];
int differenceInDays =
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date] -
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now];
According to Listing 13 of Calendrical Calculations in Apple's Date and Time Programming Guide [NSCalendar ordinalityOfUnit:NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate:myDate] gives you the number of midnights since the start of the era.
This way it's easy to check whether the date is yesterday, today, or tomorrow.
switch (differenceInDays) {
case -1:
dayString = #"Yesterday";
break;
case 0:
dayString = #"Today";
break;
case 1:
dayString = #"Tomorrow";
break;
default: {
NSDateFormatter* dayFormatter = [[NSDateFormatter alloc] init];
[dayFormatter setLocale:usLocale];
[dayFormatter setDateFormat:#"dd MMM"];
dayString = [dayFormatter stringFromDate: date];
break;
}
}
NSDateFormatter *df= [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate *dt1 = [[NSDate alloc] init];
NSDate *dt2 = [[NSDate alloc] init];
dt1=[df dateFromString:#"2011-02-25"];
dt2=[df dateFromString:#"2011-03-25"];
NSComparisonResult result = [dt1 compare:dt2];
switch (result)
{
case NSOrderedAscending: NSLog(#"%# is greater than %#", dt2, dt1); break;
case NSOrderedDescending: NSLog(#"%# is less %#", dt2, dt1); break;
case NSOrderedSame: NSLog(#"%# is equal to %#", dt2, dt1); break;
default: NSLog(#"erorr dates %#, %#", dt2, dt1); break;
}
Enjoy coding......
In Cocoa, to compare dates, use one of isEqualToDate, compare, laterDate, and earlierDate methods on NSDate objects, instantiated with the dates you need.
Documentation:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/isEqualToDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/earlierDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/laterDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/compare:
What you really need is to compare two objects of the same kind.
Create an NSDate out of your string date (#"2009-05-11") :
http://blog.evandavey.com/2008/12/how-to-convert-a-string-to-nsdate.html
If the current date is a string too, make it an NSDate. If its already an NSDate, leave it.
Here's the Swift variant on Pascal's answer:
extension NSDate {
func isLaterThanOrEqualTo(date:NSDate) -> Bool {
return !(self.compare(date) == NSComparisonResult.OrderedAscending)
}
func isEarlierThanOrEqualTo(date:NSDate) -> Bool {
return !(self.compare(date) == NSComparisonResult.OrderedDescending)
}
func isLaterThan(date:NSDate) -> Bool {
return (self.compare(date) == NSComparisonResult.OrderedDescending)
}
func isEarlierThan(date:NSDate) -> Bool {
return (self.compare(date) == NSComparisonResult.OrderedAscending)
}
}
Which can be used as:
self.expireDate.isEarlierThanOrEqualTo(NSDate())
Here's the function from Naveed Rafi's answer converted to Swift if anyone else is looking for it:
func isSameDate(#date1: NSDate, date2: NSDate) -> Bool {
let calendar = NSCalendar()
let date1comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date1)
let date2comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date2)
return (date1comp.year == date2comp.year) && (date1comp.month == date2comp.month) && (date1comp.day == date2comp.day)
}
Get Today's Date:
NSDate* date = [NSDate date];
Create a Date From Scratch:
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.year = 2015;
comps.month = 12;
comps.day = 31;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* date = [calendar dateFromComponents:comps];
Add a day to a Date:
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = 1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* tomorrow = [calendar dateByAddingComponents:comps toDate:date options:nil];
Subtract a day from a Date:
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = -1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* yesterday = [calendar dateByAddingComponents:comps toDate:date options:nil];
Convert a Date to a String:
NSDate* date = [NSDate date];
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"MMMM dd, yyyy";
NSString* dateString = [formatter stringFromDate:date];
Convert a String to a Date:
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = #"MMMM dd, yyyy";
NSDate* date = [formatter dateFromString:#"August 02, 2014"];
Find how many days are in a month:
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSRange currentRange = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
NSInteger numberOfDays = currentRange.length;
Calculate how much time something took:
NSDate* start = [NSDate date];
for(int i = 0; i < 1000000000; i++);
NSDate* end = [NSDate date];
NSTimeInterval duration = [end timeIntervalSinceDate:start];
Find the Day Of Week for a specific Date:
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSInteger dow = [cal ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];
Then use NSComparisonResult to compare date.
..
NSString *date = #"2009-05-11"
NSString *nowDate = [[[NSDate date]description]substringToIndex: 10];
if([date isEqualToString: nowDate])
{
// your code
}