Edit and Delete Existing EKEvent?

Josh Kahane picture Josh Kahane · Mar 1, 2012 · Viewed 8k times · Source

I am using the Kal calendar in my app, (hopefully that doesn't change too much) but I get an EKEvent object from that depending on the user selection on the calendar.

Anyway, how can I edit and delete an event which already exists? Namely the EKEvent that I receive?

I need to do this all programatically, I am not using any of Apple's pre-made EKEventViewController's.

I can successfully create and save new events, but Im unsure of how to edit or delete existing ones, any help would be appreciated, thanks.

Answer

Rok Jarc picture Rok Jarc · Mar 2, 2012

A complete answer would almost require a demo project.

Other approach would be simply giving you a link to Event Kit Programming Guide.

Since you did not provide any code (what you have tried already) i hope this extract from a working app will push you to the right track.

Note that i sublassed EKEventViewController due to app's specifics - this is not neccessary. I had to sublass it simply because original EKEventViewController didn't spawn with black navigationBar (this was reported as a bug also, don't now if it's fixed already).

You know how to add an event to calendar, so there's no need to write about getting a reference to EKEventStore and EKCalendar.

You're also not asking about how to retreive an event from calendar so let's assume you already have some kind of mechanism to select (receive) the event and you want to edit it. Let's say it is:

EKEvent *selectedEvent = (EKEvent *)[events objectAtIndex: selectedIndex];

I create this viewController as a property of appDelegate - you probably have better solution. appDelegate also holds eventStore and defaultCalendar reference - your approach could differ.

appDelegate.detailViewController = [[MPEventViewController alloc] initWithNibName:nil bundle:nil];  
appDelegate.detailViewController.event = selectedEvent;
appDelegate.detailViewController.eventStore = appDelegate.eventStore;   
appDelegate.detailViewController.defaultCalendar = appDelegate.defaultCalendar; 
appDelegate.detailViewController.allowsEditing = NO;
[appDelegate.navigationController pushViewController:appDelegate.detailViewController animated:YES];

Sublcassing (again, this is not neccessary but it might come useful) goes like this:

MPEventEditViewController.h

#import <Foundation/Foundation.h>
#import <EventKitUI/EventKitUI.h>

@interface MPEventViewController : EKEventViewController <EKEventEditViewDelegate> 

@property (nonatomic, strong) EKEventStore *eventStore;
@property (nonatomic, strong) EKCalendar *defaultCalendar;

- (void)editEvent:(id)sender;

@end

MPEventEditViewController.m

#import "MPEventViewController.h"
#import "----------AppDelegate.h"

@implementation MPEventViewController

@synthesize eventStore;
@synthesize defaultCalendar; 

- (void)viewDidLoad {

    [super viewDidLoad];    
    [self setTitle: [self.event title]];
    self.allowsEditing = NO;
    self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:
                                               UIBarButtonSystemItemEdit target:self action:@selector(editEvent:)];

    //this has nothing to do with the answer :)
    //[[self.navigationController navigationBar] setTintColor: [UIColor colorWithHexString: NAVBAR_TINT_COLOR]]; 
}

- (void)editEvent:(id)sender {

    EKEventEditViewController *addController = [[EKEventEditViewController alloc] initWithNibName:nil bundle:nil];

    //this has nothing to do with the answer :)
    //[addController.navigationBar setTintColor: [UIColor colorWithHexString: NAVBAR_TINT_COLOR]]; 
    addController.eventStore = self.eventStore;
    addController.event = self.event;
    addController.navigationBar.barStyle = UIBarStyleBlack;
    addController.editViewDelegate = self;

    [self presentModalViewController:addController animated:YES];

}

- (void)eventEditViewController:(EKEventEditViewController *)controller 
          didCompleteWithAction:(EKEventEditViewAction)action {

    NSError *error = nil;
    EKEvent *thisEvent = controller.event;

    switch (action) {
        case EKEventEditViewActionCanceled:
            break;

        case EKEventEditViewActionSaved:
            [controller.eventStore saveEvent:controller.event span: EKSpanFutureEvents error:&error];
            break;

        case EKEventEditViewActionDeleted:

            [controller.eventStore removeEvent:thisEvent span: EKSpanFutureEvents error:&error];
            break;

        default:
            break;
    }

    //here would be the place to reload data if you hold it in some kind of UITableView    
    [controller dismissModalViewControllerAnimated:YES];
}


- (EKCalendar *)eventEditViewControllerDefaultCalendarForNewEvents:(EKEventEditViewController *)controller {
    EKCalendar *calendarForEdit = self.defaultCalendar;
    return calendarForEdit;
}

- (void)dealloc {

    eventStore = nil;
    defaultCalendar = nil;    
}

@end

Only after writing all this i remembered there is a great sample code SimpleEKDemo. In fact some of this posted code is probably originates from there.

EDIT:

After the question was edited the above answer became off-topic.

In that case you should take a look at EKCalendarItem and EKevent.

You can change allmost all properties programatically (most of them are inherited from EKCalendarItem).

Maybe you were distracted for example becaues hasNotes is readonly. That is because hasNotes is kind of a function and not a real property. Properties like notes, atendees, startDate, endDate etc. are perfectly editable.

For saving modified event you can still use:

 NSError error = nil;
 [self.eventStore saveEvent:event span: EKSpanFutureEvents error:&error];

And for deleting it:

 NSError error = nil;
 [self.eventStore removeEvent:event span: EKSpanFutureEvents error:&error];

EDIT2: for deleting all events try this:

//assuming self.eventStore is already properly set in code

//identifierArray would be your NSMutableArray holding event identifiers
//change the name according to your code

NSError error = nil;

for (NSString *eventIdentifier in removeAllObjects) {

    EKEvent *event = [self.eventStore eventWithIdentifier:eventIdentifier];

    [self.eventStore removeEvent:event span:EKSpanFutureEvents error:&error];
}

//now you can also clear identifiers
[removeAllObjects removeAllObjects];

Note: there's no guarantee you'll be able to delete all events - only events from default calendar which is set by usert in settings app.