EkEvent is showing on each day - iphone

I am using this code to add an event to a device however on calender in device its getting shown on each date upto the end date of the event
NSString *GoalDate = [[[DFDateFormatterFactory sharedFactory]
dateFormatterWithFormat:#"yyyy-MM-dd" andLocaleIdentifier:#"en_US"]
stringFromDate:self.datepicker.date];
[AppHelper saveToUserDefaults:GoalDate withKey:#"goalsdates"];
NSInteger dummyInteger = [[AppHelper userDefaultsForKey:#"event"]intValue];
if(dummyInteger!=0)
{
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (!granted)
{ return;
}
EKRecurrenceEnd *endRecurrence = nil;
endRecurrence = [EKRecurrenceEnd recurrenceEndWithEndDate:self.datepicker.date];
EKRecurrenceRule *recurrence;
if(dummyInteger==1)
{
recurrence= [[EKRecurrenceRule alloc] initRecurrenceWithFrequency: EKRecurrenceFrequencyDaily
interval:1 daysOfTheWeek:nil daysOfTheMonth:nil monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:endRecurrence];
}
if(dummyInteger==2)
{
recurrence = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency: EKRecurrenceFrequencyWeekly interval:7 daysOfTheWeek:nil daysOfTheMonth:nil monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil
end:endRecurrence];
}
if(dummyInteger==3)
{
recurrence = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency: EKRecurrenceFrequencyWeekly interval:1 daysOfTheWeek:nil daysOfTheMonth:nil monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:endRecurrence];
}
if(dummyInteger==4)
{
recurrence = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency: EKRecurrenceFrequencyYearly interval:1 daysOfTheWeek:nil daysOfTheMonth:nil monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:endRecurrence];
}
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = [AppHelper userDefaultsForKey:#"nameofagoal"];
event.allDay = false;
event.startDate =[NSDate date];
// event.endDate = [event.startDate dateByAddingTimeInterval:60*60*24*7]; //set 1 hour meeting
event.endDate = self.datepicker.date;
// event.endDate = endDate;
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *err = nil;
[event addRecurrenceRule: recurrence];
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
savedEventId = event.eventIdentifier; //this is so you can access this event later
}];

By default event kit adds event from start to end date. If your start and end date are different. Then it will show on all the days from start to end. If you want to show event only on start day and end day of event then you must have to add two events with same name but different ending dates.
You can also set allDay property of the event to YES. In this case event will not cover the whole screen if you are on the day view of calendar.

Related

how i use iPhone calendar add event?

I want use iPhone calendar add Event.
I try ti.com.calendar module from github but in this module only save startTime EndTime, Title and details.
but, not use allDay repeat or not reminder.
How i use this. in calendar?
I also user notification for reminder. but, after delete event. the notification is not delete.
any suggestion is appreciated
bellow is peace of code. date for alarm is using to match work hours (users don't like to wakeup to do job :)
eventStore = [[EKEventStore alloc] init];
EKEvent *newEvent = [EKEvent eventWithEventStore:eventStore];
newEvent.calendar = eventStore.defaultCalendarForNewEvents;
NSString *titleForEvent = [NSString stringWithFormat:#"In country:%# will be:\n%# event",[mo valueForKey:#"name"],[mo valueForKey:#"necessaryData"]];
newEvent.title = titleForEvent;
newEvent.allDay = YES;
NSDate *date = [mo valueForKey:#"date"];
NSDate *dateAlarm = [mo valueForKey:#"dateAlarm"];
EKAlarm *alarm = [EKAlarm alarmWithRelativeOffset:[dateAlarm timeIntervalSinceDate:date]];
if (dateAlarm < [NSDate date]){
dateAlarm = [NSDate dateWithTimeIntervalSinceNow:+18000];
NSDateFormatter *dateForm = [[NSDateFormatter alloc]init];
[dateForm setDateFormat:#"%HH"];
NSString *hourOfAlarm = [dateForm stringFromDate:dateAlarm];
[dateForm release];
NSNumberFormatter *numberForm = [[NSNumberFormatter alloc] init];
NSNumber *hour = [numberForm numberFromString:hourOfAlarm];
[numberForm release];
int difference = 0;
if ([hour intValue] < 9) difference = (9 - [hour intValue]) *3600;
if ([hour intValue] > 17) difference = (17 - [hour intValue]) *3600;
if (difference != 0) {
NSTimeInterval interval = 18000 + difference;
dateAlarm = [NSDate dateWithTimeIntervalSinceNow:interval];
}
alarm = [EKAlarm alarmWithRelativeOffset:[dateAlarm timeIntervalSinceDate:date]];
}
newEvent.startDate = date;
newEvent.endDate = date;
//EKAlarm *alarm = [EKAlarm alarmWithRelativeOffset:[dateAlarm timeIntervalSinceDate:date]];
newEvent.alarms = [NSArray arrayWithObject:alarm];
NSError *error;
BOOL saved = [eventStore saveEvent:newEvent span:EKSpanThisEvent error:&error];
if (!saved && error) {
NSLog(#"%#",[error localizedDescription]);
} else [mo setValue:newEvent.eventIdentifier forKey:#"eventIdentifier"];

EKRecurrenceRule - add recurring events but exclude weekends

I have this method which adds events to native iphone calendar.
It is already adding monthly reminders successfully - but I want to force any monthy reminders to fall into week days (not weekends).
The NSDictionary model is simply
Id:
Start_Date__c
Finish_Date__c
Payment_Interval__c = Monthly
- (void)addRecurringEventsForPartnership:(NSDictionary *)dict{
ENTER_METHOD;
NSError *error = nil;
EKEvent *startEvent = [EKEvent eventWithEventStore:self.eventStore];
startEvent.calendar = self.defaultCalendar;
startEvent.availability = EKEventAvailabilityFree;
startEvent.startDate = [NSDate dateWithLongFormatString:[dict valueForKey:#"Start_Date__c"]];
startEvent.allDay = YES;
// startEvent.endDate = [startEvent.startDate dateByAddingTimeInterval:30*60];
startEvent.title = [dict theNameValue];
//http://stackoverflow.com/questions/7718006/xcode-why-is-my-event-not-being-added-to-the-calendar
if ([startEvent.startDate isEqualToDate:startEvent.endDate]) {
startEvent.endDate = [startEvent.startDate dateByAddingTimeInterval:30*60];;
}
// if
if ([[dict valueForKey:#"Payment_Interval__c"] isEqualToString:#"Monthly"]) {
EKRecurrenceFrequency freq = EKRecurrenceFrequencyMonthly;
int recurrenceInterval = 1;
EKRecurrenceRule *rule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:freq interval:recurrenceInterval end:nil];
startEvent.recurrenceRule = rule;
startEvent.notes = [NSString stringWithFormat:#"Id:%#",[dict valueForKey:#"Id"]];
// [self.eventStore removeEvent:startEvent span:EKSpanThisEvent error:&error];
[self.eventStore saveEvent:startEvent span:EKSpanThisEvent error:&error];
if (error != nil)
{
DLog(#"WARNING:%#",error.description);
// TODO: error handling here
}
}
// DLog(#"startEvent.endDate:%#",startEvent.endDate);
EKEvent *finishEvent = [EKEvent eventWithEventStore:self.eventStore];
finishEvent.calendar = self.defaultCalendar;
finishEvent.availability = EKEventAvailabilityFree;
finishEvent.startDate = [NSDate dateWithLongFormatString:[dict valueForKey:#"Finish_Date__c"]];
finishEvent.allDay = YES;
finishEvent.title = [NSString stringWithFormat:#"%# - Finish",[dict theNameValue]];
finishEvent.notes = [NSString stringWithFormat:#"Id:%#",[dict valueForKey:#"Id"]];
[self.eventStore saveEvent:finishEvent span:EKSpanThisEvent error:&error];
if (error != nil)
{
DLog(#"WARNING:%#",error.description);
// TODO: error handling here
}
}
Couldn't you use NSDateFormatter to get the numeric day of the week and then adjust by subtracting or adding 1 or 2 depending on which day it returned?
[dateFormatter setDateFormat:#"c"];
Will return numeric (1-7) day of the week, I believe
Here's something that works (at least in iOS7, didn't test on other systems):
EKRecurrenceRule *er = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:EKRecurrenceFrequencyMonthly interval:1
daysOfTheWeek:#[[EKRecurrenceDayOfWeek dayOfWeek:2], // Monday
[EKRecurrenceDayOfWeek dayOfWeek:3], // Tuesday
[EKRecurrenceDayOfWeek dayOfWeek:4], // Wednesday
[EKRecurrenceDayOfWeek dayOfWeek:5], // Thursday
[EKRecurrenceDayOfWeek dayOfWeek:6]] // Friday
daysOfTheMonth:#[#1, #2]
monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:nil];
event.recurrenceRules = #[er];

Add an event into iCal in iPhone application

There is a requirement in my application in which, when I take an appointment of a doctor for a particular day, that day should be added in iCal. and it should generate an alert view on that particular day.
So, I am not getting how to add an event in iCal. Please give me some answer for this.
The scenario is, I do have a string (NSString) of "date" and "notes" for that particular appointment. Then, how to insert all this information into iCal.
Code:
- (NSArray *)fetchEventsForToday {
NSDate *startDate = [NSDate date];
// endDate is 1 day = 60*60*24 seconds = 86400 seconds from startDate
NSDate *endDate = [NSDate dateWithTimeIntervalSinceNow:86400];
// Create the predicate. Pass it the default calendar.
NSArray *calendarArray = [NSArray arrayWithObject:defaultCalendar];
NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate endDate:endDate
calendars:calendarArray];
// Fetch all events that match the predicate.
NSArray *events = [self.eventStore eventsMatchingPredicate:predicate];
return events;
}
// Overriding EKEventEditViewDelegate method to update event store according to user actions.
- (void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action {
NSError *error = nil;
EKEvent *thisEvent = controller.event;
switch (action) {
case EKEventEditViewActionCanceled:
// Edit action canceled, do nothing.
break;
case EKEventEditViewActionSaved:
// When user hit "Done" button, save the newly created event to the event store,
// and reload table view.
// If the new event is being added to the default calendar, then update its
// eventsList.
if (self.defaultCalendar == thisEvent.calendar) {
[self.eventsList addObject:thisEvent];
}
[controller.eventStore saveEvent:controller.event span:EKSpanThisEvent error:&error];
[self.tableView reloadData];
break;
case EKEventEditViewActionDeleted:
// When deleting an event, remove the event from the event store,
// and reload table view.
// If deleting an event from the currenly default calendar, then update its
// eventsList.
if (self.defaultCalendar == thisEvent.calendar) {
[self.eventsList removeObject:thisEvent];
}
[controller.eventStore removeEvent:thisEvent span:EKSpanThisEvent error:&error];
[self.tableView reloadData];
break;
default:
break;
}
// Dismiss the modal view controller
[controller dismissModalViewControllerAnimated:YES];
}
// Set the calendar edited by EKEventEditViewController to our chosen calendar - the default calendar.
- (EKCalendar *)eventEditViewControllerDefaultCalendarForNewEvents:(EKEventEditViewController *)controller
{
EKCalendar *calendarForEdit = self.defaultCalendar;
return calendarForEdit;
}
I have used these functions and delegate methods. Please give me idea that, when the user gets alerted for the reminder, how to open up that information regarding that event?
You need the EventKit framework. You can ask the EKEventStore for its calendars, and then use those calendars to create a predicate that lets you find events that match the criteria you're looking for. Or you can create a new EKEvent object and save it into the event store.
Based on Apple Documentation, this has changed a bit as of iOS 6.0.
1) You should request access to the user's calendar via "requestAccessToEntityType:completion:" and execute the event handling inside of a block.
2) You need to commit your event now or pass the "commit" param to your save/remove call
Everything else stays the same...
Add the EventKit framework and #import to your code.
To add an event:
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = #"Event Title";
event.startDate = [NSDate date]; //today
event.endDate = [event.startDate dateByAddingTimeInterval:60*60]; //set 1 hour meeting
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
NSString *savedEventId = event.eventIdentifier; //this is so you can access this event later
}];
Remove the event:
EKEventStore* store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent* eventToRemove = [store eventWithIdentifier:savedEventId];
if (eventToRemove) {
NSError* error = nil;
[store removeEvent:eventToRemove span:EKSpanThisEvent commit:YES error:&error];
}
}];

How to delete calendar events faster?

Following code works and deletes all calendar events from iPhone calendar database.
But events are deleting very slow: 2 events per second on iPhone 3GS.
So if you have 3000 events - then it's 25 minutes to erase them...
How would you optimize this code? Maybe I am doing something wrong? Thanks.
- (void)deleteAllCalendarEventsFromIPhone:(NSError **)error {
EKEventStore *store = [[EKEventStore alloc] init];
NSUInteger beginYear = 1900;
NSUInteger endYear = 2100;
while (beginYear < endYear) {
NSPredicate *predicate =
[store predicateForEventsWithStartDate:[self createDateWithYear:beginYear month:1 day:1]
endDate:[self createDateWithYear:beginYear + 4 month:1 day:1]
calendars:nil];
NSArray *eventList = [store eventsMatchingPredicate:predicate];
for (EKEvent *event in eventList) {
success = [store removeEvent:event span:EKSpanThisEvent error:nil];
}
beginYear += 4;
}
[store release];
}
iOS 5.0 has a new removeEvent: method that allows you not to commit changes until the very end. I haven't tested it yet, but that sounds to be exactly what you need here.
Maybe because it is not the usage of EKEventStore !
Removing all user event is quite dangerous ...
-(void)deleteElementFromCalendarDB {
CFGregorianDate gregorianStartDate, gregorianEndDate;
CFGregorianUnits startUnits = {-2, 0, 0, 0, 0, 0};
CFGregorianUnits endUnits = {1, 0, 0, 0, 0, 0};
CFTimeZoneRef timeZone = CFTimeZoneCopySystem();
gregorianStartDate = CFAbsoluteTimeGetGregorianDate(
CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(),
timeZone,startUnits),timeZone);
gregorianStartDate.hour = 0;
gregorianStartDate.minute = 0;
gregorianStartDate.second = 0;
gregorianEndDate = CFAbsoluteTimeGetGregorianDate(
CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(),
timeZone, endUnits),timeZone);
gregorianEndDate.hour = 0;
gregorianEndDate.minute = 0;
gregorianEndDate.second = 0;
NSDate* startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:
CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
NSDate* endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:
CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];
CFRelease(timeZone);
NSError *err;
NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate
endDate:endDate
calendars:nil];
NSArray *eventListS = [self.eventStore eventsMatchingPredicate:predicate];
for (EKEvent *event in eventListS) {
[self.eventStore removeEvent:event span:EKSpanFutureEvents error:&err];
}
if (err == noErr) {
UIAlertView *alert =[[UIAlertView alloc]itWithTitle:#"All Events were deleted" message:#"How about that?"
delegate:nil
cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}

How can I programmatically create an iCal event in the default calendar?

How can I use Objective-C to programmatically create an iCal event in the default calendar? I want to check whether the event already exists and set the button state accordingly.
An example of how to programmatically create an iCAL event in the default calendar, using Objective-C. The code checks if the event already exists, and sets the button state accordingly. Here is the code by #codeburger:
-(void)initCalendar {
// An array of 1 dictionary object, containing START and END values.
NSMutableArray* pvDict = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:PV_URL ]];
// Check if the private view event already exists in the default calendar.
// Then set the calendar button state.
// Get a entry point to the Calendar database.
self.store = [[EKEventStore alloc ] init ];
// Get an array of all the calendars.
NSArray *calendars = store.calendars;
// Get the default calendar, set by the user in preferences.
EKCalendar *defaultCal = store.defaultCalendarForNewEvents;
// Find out if this calendar is modifiable.
BOOL isDefaultCalModifiable = defaultCal.allowsContentModifications ;
// Create an event in the default calendar.
self.event = [ EKEvent eventWithEventStore:store ];
self.event.title = CHELSEA_SPACE ;
self.event.location = CHELSEA_ADDRESS ;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyy-MM-dd HH:mm:ss.S"];
NSString *startString = [[ pvDict objectAtIndex:0] objectForKey:#"starts" ];
NSDate *dateStart = [dateFormatter dateFromString:startString];
NSString *endString = [[ pvDict objectAtIndex:0] objectForKey:#"ends" ];
NSDate *dateEnd = [dateFormatter dateFromString:endString];
self.event.startDate = dateStart;
self.event.endDate = dateEnd;
self.event.calendar = defaultCal ;
// Alternative code to add 2.5 hours to start time.
// [[NSDate alloc] initWithTimeInterval:9000 sinceDate:event.startDate];
// Search for events which match this date/time start and end.
// Compare the matched events by event TITLE.
NSPredicate *predicate = [store predicateForEventsWithStartDate:event.startDate
endDate:event.endDate calendars:calendars];
NSArray *matchingEvents = [store eventsMatchingPredicate:predicate];
self.calendarButton.enabled = NO;
if( ! isDefaultCalModifiable ) {
// The default calendar is not modifiable
return ;
}
if ( [ matchingEvents count ] > 0 ) {
// There are already event(s) which match this date/time start and end.
// Check if this event is the PV
EKEvent *anEvent;
int j;
for ( j=0; j < [ matchingEvents count]; j++) {
anEvent = [ matchingEvents objectAtIndex:j ] ;
if([ CHELSEA_SPACE isEqualToString: anEvent.title ]) {
// PV event already exists in calendar.
return;
}
}
[ anEvent release ];
}
self.calendarButton.enabled = YES;
[ pvDict release ];
}
-(void)addEventToCalendar:(id)sender {
NSError *error;
BOOL saved = [self.store saveEvent:self.event span:EKSpanThisEvent error:&error];
NSLog(#"Saved calendar event = %#\n", (saved ? #"YES" : #"NO"));
self.calendarButton.enabled = NO;
}
I've seen this question with no answer and felt like it should be edited giving full credit to #codeburger.
EKEventStore *eventStore = [[EKEventStore alloc] init];
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
NSDate *date = [[NSDate alloc ]init];//today,s date
event.title = #"remainder";//title for your remainder
event.startDate=date;//start time of your remainder
event.endDate = [[NSDate alloc] initWithTimeInterval:1800 sinceDate:event.startDate];//end time of your remainder
NSTimeInterval interval = (60 *60)* -3 ;
EKAlarm *alarm = [EKAlarm alarmWithRelativeOffset:interval]; //Create object of alarm
[event addAlarm:alarm]; //Add alarm to your event
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
NSError *err;
NSString *ical_event_id;
//save your event
if([eventStore saveEvent:event span:EKSpanThisEvent error:&err]){
ical_event_id = event.eventIdentifier;
NSLog(#"%#",ical_event_id);
}
for more info check this link
sample for EKEvent