Deleting an event from iPhone's calendar - ios

I am trying to delete an event from the Calendar on user request. This is what I've come up with:
// Deleting Event
EKEventStore *eventStore = [[EKEventStore alloc] init];
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = appDelegate.title1;
event.startDate = appDelegate.recAddDate;
event.endDate = appDelegate.currentDateName;
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
NSError *err;
[eventStore removeEvent:event span:EKSpanThisEvent error:&err];
Below is the function I'm calling to remove the event from the event array. Items array is used to fetch events from iPhone calendar
- (BOOL)removeEvent:(EKEvent *)event span:(EKSpan)span error:(NSError **)error{
VoiceRecorderAppDelegate *appDelegate = (VoiceRecorderAppDelegate *)[[UIApplication sharedApplication] delegate];
[items removeObjectAtIndex:appDelegate.objectindexpath];
}

Firstly, save the eventId for the event while adding/saving events to the calendar.
[eventStore saveEvent:event span:EKSpanThisEvent error:&err];
NSString* str = [[NSString alloc] initWithFormat:#"%#", event.eventIdentifier];
[arrayofEventId addObject:str];
and then identify the event you want to remove ande then remove that event.
EKEventStore* store = [[EKEventStore alloc] init];
EKEvent* eventToRemove = [store eventWithIdentifier:[arrayofEventId objectAtIndex:i]];
if (eventToRemove != nil) {
NSError* error = nil;
[store removeEvent:eventToRemove span:EKSpanThisEvent error:&error];
}
Also don't forget to remove that event from arrayofEventId as well.

You can achieve this in the following ways:
By creating an NSpredicate using the date range withing which you
want to delete events, 86400 being the duration of a day in events, in
this piece of code I am deleting month old events. I am using a
dispatch queue, as the no. of events fetched may be large, and to keep the UI free.
First Create the event store and check access(access check required only iOS6 onwards):
- (void)addEventsToCalendar {
EKEventStore *eventStore = [[EKEventStore alloc] init];
if ([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)]) {
//implementation for devices running OS version iOS 6.0 onwards.
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted) {
[self removeEventsFromStore:eventStore];
} else {
//perform for No Access using Error
}];
} else {
//implementation for devices running OS version lower than iOS 6.0.
[self removeEventsFromStore:eventStore];
}
}
Then remove events from the store:
- (void)removeEventsFromStore:(EKEventStore*)eventStore {
NSDate *startDate = [NSDate dateWithTimeIntervalSinceNow:-30 * 86400];
NSDate *endDate = [NSDate date];
dispatch_queue_t queue = dispatch_queue_create("com.arc.calendar", NULL);
dispatch_async(queue, ^{
NSArray *calendarArray = [NSArray arrayWithObject:[PWCCalendar getCalendarForEventStore:eventStore]];
NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:startDate endDate:[NSDate dateWithTimeInterval:ONE_DAY_DURATION sinceDate:endDate] calendars:calendarArray];
NSArray *eventArray = [eventStore eventsMatchingPredicate:predicate];
for (EKEvent *event in eventArray) {
[eventStore removeEvent:event span:EKSpanThisEvent commit:YES error:NULL];
}
dispatch_async(dispatch_get_main_queue(), ^{
//Get the main Queue and perform UPdates
});
});
}
This is the Long way, use it to delete events in bulk. But if you need to delete only One event, then save the events identifier to `NSUserDefaults(after generating the event)
[eventStore saveEvent:event span:EKSpanThisEvent commit:YES error:NULL];
[[NSUserDefaults standardUserDefaults] setObject:[event eventIdentifier] forKey:#"Event ID"];
and then fetch it back while removing using
[eventStore eventWithIdentifier:#"Event ID"];
and then remove it from the store using
[eventStore removeEvent:event span:EKSpanThisEvent commit:YES error:NULL];
For more clarifications on the other methods to fetch events or calendar, pelase refer to EventStore docs: http://developer.apple.com/library/ios/#documentation/EventKit/Reference/EKEventStoreClassRef/Reference/Reference.html#//apple_ref/doc/uid/TP40009567 or to the Calendar and Reminder Programming guide: http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/EventKitProgGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009765

Related

Open "Event Details" in calendar app with specific event id

I am trying to open calendar with specific event, I have added events programmatically and all the IDs of these event are persistent.
This is how i add event
-(IBAction)addEvent:(id)sender{
EKEventStore *store = [[EKEventStore alloc]init];
[store requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = #"Demo Title";
NSDateComponents *comps=[[NSDateComponents alloc]init];
[comps setDay:4];
[comps setMonth:10];
[comps setYear:2016];
[comps setHour:12];
[comps setMinute:1];
NSDate *date=[[[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian] dateFromComponents:comps];
_date=date;
event.startDate = date;
event.endDate=date;
event.notes=#"This is event description";
EKAlarm *alarm=[EKAlarm alarmWithAbsoluteDate:date];
[event addAlarm:alarm];
event.calendar = [store defaultCalendarForNewEvents];
NSError *err=nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
}];
}
The event is added successfully and i'm also able to open calendar app but the thing is i can't navigate inside the event detail in calendar
here is how i open calendar
-(IBAction)openCalender:(id)sender{
NSInteger interval = [_date timeIntervalSinceReferenceDate];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"calshow:%ld?eventid=%#", (long)interval,_eventID]];
NSLog(#"%#",url);
[[UIApplication sharedApplication] openURL:url];
}
What i want is in below screenshot
What i'm getting is
any idea?
To answer my own question, this isn't possible with any of public API
I searched over a year but this is not possible with any public API, but i guess there might be some private API to do this (and probably doing that will get our app rejected).
Widget of calendar app is doing the same what i want to do but it's Apple's API wont allow us to use it. lol
I really don't think there's a way to do this. Even when creating a new calendar event from the default Mail app opens the calendar day view. If this functionality was possible I'm sure they would have at least implemented it in the default mail app.

Error when trying to delete EKCalendar from EKStore

I am trying to remove a EKCalendar that I have created inside my iOS app using the following method.
- (void)DeleteCalendar
{
EKEventStore *eventStore = [[EKEventStore alloc] init];
EKEntityType type = EKEntityTypeEvent;
NSArray *calendars = [eventStore calendarsForEntityType:type];
for (EKCalendar *thisCalendar in calendars){
NSLog(#"Calendar: %#", thisCalendar.title);
if ([thisCalendar.title isEqualToString:[NSString stringWithFormat:#"%#%#",CALENDARPREFIX, _currentCName]]) {
NSError *err;
[eventStore removeCalendar:thisCalendar commit:YES error:&err];
if (!err) {
NSLog(#"deleted %#", thisCalendar.title);
} else {
NSLog(#"%#", err.localizedDescription);
}
}
}
}
However when I run this method I get the following error from the last else statement.
That event does not belong to that event store
I have read that there is a bug in removeCalendar: however was hoping someone else may have experienced this and can help me fix the issue.

Delete EKEvent from EKEventStore from iOS Calendar App

I have added an event on the default calendar on iPhone using the following code:
EKEventStore *store=[[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) {
return ;
}
EKEvent *event=[EKEvent eventWithEventStore:store];
event.title=#"This is the event";
event.startDate=[NSDate date];
event.endDate =[event.startDate dateByAddingTimeInterval:60*60];
event.allDay=YES;
NSURL *url=[NSURL URLWithString:#"http://www.google.com"];
event.URL=url;
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *errr=nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&errr]; // NSLog(#"%#",errr); // NSLog(#"%#",event.eventIdentifier);
}];
Now I want to delete this event.
The code I tried is this:
EKEventStore *store1=[[EKEventStore alloc]init];
NSPredicate *predicate=[store1 predicateForEventsWithStartDate:[[tableViewScheduleArray objectAtIndex:btn.tag] objectForKey:#"Schedule_Date"] endDate:[[tableViewScheduleArray objectAtIndex:btn.tag] objectForKey:#"Schedule_End_Time"] calendars:nil];
NSArray *arr=[store eventsMatchingPredicate:predicate];
dispatch_async(dispatch_get_main_queue(), ^{
[store1 removeEvent:[arr objectAtIndex:0] span:EKSpanThisEvent commit:YES error:nil];
});
It didn't work, but it didn't result in an error either.
I have tried several pieces of code from Stack Overflow but neither of them worked.
I got the solution,
It was a silly mistakes by me.
the property "store" which is not declare as strong.
as i changed it worked.
And Above code is working properly.

attach text from UIViewController to Inbuilt iphone calendar

In my Application i need to attach(show iphone inbuilt calender) in-built iphone calendar on the UIButton action. More, The text from my UIViewControllers UILabel, I need attach that text in iphones in built calendar as reminder, where user is free to select date according his need.
I had found like EventKIt framework may be useful to me, But i am not sure. And i am also not familiar with EventKit framework.
Just Use this example with EventKit framwork.
-(IBAction)buttonAction:(id)sender
{
EKEventStore *eventStore = [[EKEventStore alloc] init];
EKEventStore *eventStore = [[[EKEventStore alloc] init] autorelease];
if([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)]) {
// iOS 6 and later
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted){
//---- codes here when user allow your app to access theirs' calendar.
[self performCalendarActivity:eventStore];
}else
{
//----- codes here when user NOT allow your app to access the calendar.
}
}];
}
else {
//---- codes here for IOS < 6.0.
[self performCalendarActivity:eventStore];
}
}
-(void)performCalendarActivity:(EKEventStore *)eventStore
{
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = #"EVENT TITLE";
event.startDate = [[NSDate alloc] init];
event.endDate = [[NSDate alloc] initWithTimeInterval:600 sinceDate:event.startDate];
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
NSError *err;
[eventStore saveEvent:event span:EKSpanThisEvent error:&err];
}
Don't forget to import #import <EventKit/EventKit.h> to your view controller.

iOS - Delete Recurring EKEvent, event appears again

I have a recurring event in calendar. I'm delete a single event using this code [store removeEvent:event span:EKSpanThisEvent commit:YES error:&errorThis]; and this methods returns true but the event is not deleted from the calendar.
On EKCalendarItem Class reference using the property calendarItemExternalIdentifier you find this
Recurring event identifiers are the same for all occurrences. If you wish to differentiate between occurrences, you may want to use the start date
So you want delete only a recurrence you have to do something like this:
NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:calendars];
NSArray *theEvents = [eventStore eventsMatchingPredicate:predicate];
NSString *recurrenceEventIdentifier;
for(EKEvent * theEvent in theEvents)
{
if([theEvent.eventIdentifier isEqualToString: recurrenceEventIdentifier]
&& ![eventStore removeEvent:theEvent span:EKSpanThisEvent error:&error])
{
NSLog(#"Error in removing event: %#",error);
}
}
Your method instead, deletes only the first occurrence. If you want delete all recurring events just change "span" parameter in EKSpanFutureEvents.
EDIT: Now only deletes the matching recurrent event, not everything.
Please make sure you have only one instance of EKEventStore in singleton pattern in your app :
static EKEventStore *eventStore = nil;
+ (EKEventStore *)getEventStoreInstance
{
if (eventStore == nil){
#synchronized(self){
if (eventStore == nil){
eventStore = [[EKEventStore alloc] init];
}
}
}
return(eventStore);
}

Resources