Is there any way to add iCal event to the iPhone Calendar from the custom App?
11 Answers
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 <EventKit/EventKit.h>
to your code.
In my example, I have a NSString *savedEventId instance property.
To add an event:
EKEventStore *store = [EKEventStore new];
[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.calendar = [store defaultCalendarForNewEvents];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
self.savedEventId = event.eventIdentifier; //save the event id if you want to access this later
}];
Remove the event:
EKEventStore* store = [EKEventStore new];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent* eventToRemove = [store eventWithIdentifier:self.savedEventId];
if (eventToRemove) {
NSError* error = nil;
[store removeEvent:eventToRemove span:EKSpanThisEvent commit:YES error:&error];
}
}];
This adds events to your default calendar, if you have multiple calendars then you'll have find out which one that is
Swift version
You need to import the EventKit framework
import EventKit
Add event
let store = EKEventStore()
store.requestAccessToEntityType(.Event) {(granted, error) in
if !granted { return }
var event = EKEvent(eventStore: store)
event.title = "Event Title"
event.startDate = NSDate() //today
event.endDate = event.startDate.dateByAddingTimeInterval(60*60) //1 hour long meeting
event.calendar = store.defaultCalendarForNewEvents
do {
try store.saveEvent(event, span: .ThisEvent, commit: true)
self.savedEventId = event.eventIdentifier //save event id to access this particular event later
} catch {
// Display error to user
}
}
Remove event
let store = EKEventStore()
store.requestAccessToEntityType(EKEntityTypeEvent) {(granted, error) in
if !granted { return }
let eventToRemove = store.eventWithIdentifier(self.savedEventId)
if eventToRemove != nil {
do {
try store.removeEvent(eventToRemove, span: .ThisEvent, commit: true)
} catch {
// Display error to user
}
}
}

- 37,241
- 25
- 195
- 267

- 12,831
- 4
- 56
- 53
-
6does not work for me, everything goes w/o errors but no event in calendar – Boris Gafurov Oct 02 '13 at 15:30
-
Everything is storing in ekevent object but not storing inside the calendar hlp me – Jan 28 '14 at 10:02
-
1@William T: Can I present Add Event screen of Calendar app (using URL Scheme) and pass event's info so that when Add Event screen appear, it will have pre filled data. User just need to press add event button. In your example event added without any indication to user. – Ans May 17 '14 at 10:01
-
1if all seems to work yet no calendar appears, check to see if Cloud VS Local calendars is the issue. If you have a mix of Cloud and Local Calendars, Cloud calendars can force the local calendars to become hidden. – zonabi Jun 09 '14 at 17:19
-
@William It is working for me. Here i am facing one problem if i add more than one events to the calendar and tried to remove event from the calendar, It is removing only last event from the calendar. How to get identifier for event when we are removing from the calendar. – Logger Sep 29 '14 at 08:31
-
2@ReddyBasha when you add the event, you need to save off the eventIdentifier and store it for future use. You should use that event id when you go to remove it. – William T. Nov 03 '14 at 00:10
You can do this using the Event Kit framework in OS 4.0.
Right click on the FrameWorks group in the Groups and Files Navigator on the left of the window. Select 'Add' then 'Existing FrameWorks' then 'EventKit.Framework'.
Then you should be able to add events with code like this:
#import "EventTestViewController.h"
#import <EventKit/EventKit.h>
@implementation EventTestViewController
- (void)viewDidLoad {
[super viewDidLoad];
EKEventStore *eventStore = [[EKEventStore alloc] init];
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];
}
@end

- 3,363
- 7
- 42
- 62

- 6,521
- 8
- 53
- 73
-
18Thanks for posting this. Just a reminder to all who read this: take care to watch for memory leaks. There are a couple in this code sample. Also, best practices would dictate that you check the value of 'err' after saveEvent:span:error and handle things accordingly. – David Carney Jul 06 '10 at 21:37
-
Do you know how to add recurrence event? like an event for every monday? – Jay Vachhani Sep 09 '10 at 07:45
-
5Add recurrence event programmatically: check this out http://developer.apple.com/library/ios/#documentation/EventKit/Reference/EKRecurrenceRuleClassRef/Reference/Reference.html#//apple_ref/doc/c_ref/EKRecurrenceRule. Another option is to use the default framework-supplied view controllers for adding/editing events (like the Calendar At-A-Glance app http://bit.ly/cJq4Bh). For this option, see http://developer.apple.com/library/ios/#documentation/EventKitUI/Reference/EKEventEditViewControllerClassRef/Reference/Reference.html – DenTheMan Dec 06 '10 at 10:12
-
To add frameworks in XCode 4 see this SO question: http://stackoverflow.com/questions/3352664/how-to-add-existing-frameworks-in-xcode-4 – Nate Mar 19 '11 at 01:45
-
1
Yes there still is no API for this (2.1). But it seemed like at WWDC a lot of people were already interested in the functionality (including myself) and the recommendation was to go to the below site and create a feature request for this. If there is enough of an interest, they might end up moving the ICal.framework to the public SDK.

- 2,303
- 14
- 10
Calendar access is being added in iPhone OS 4.0:
Calendar Access
Apps can now create and edit events directly in the Calendar app with Event Kit.
Create recurring events, set up start and end times and assign them to any calendar on the device.

- 64,770
- 52
- 221
- 239
Swift 4.0 implementation :
use import in top of page by import EventKit
then
@IBAction func addtoCalendarClicked(sender: AnyObject) {
let eventStore = EKEventStore()
eventStore.requestAccess( to: EKEntityType.event, completion:{(granted, error) in
if (granted) && (error == nil) {
print("granted \(granted)")
print("error \(error)")
let event = EKEvent(eventStore: eventStore)
event.title = "Event Title"
event.startDate = Date()
event.endDate = Date()
event.notes = "Event Details Here"
event.calendar = eventStore.defaultCalendarForNewEvents
var event_id = ""
do {
try eventStore.save(event, span: .thisEvent)
event_id = event.eventIdentifier
}
catch let error as NSError {
print("json error: \(error.localizedDescription)")
}
if(event_id != ""){
print("event added !")
}
}
})
}

- 11,454
- 9
- 54
- 64

- 2,141
- 1
- 28
- 33
-
could u help me with google calendar regarding same answer @Dashrath – Dilip Tiwari Dec 15 '17 at 13:02
You can add the event using the Event API like Tristan outlined and you can also add a Google Calendar event which shows up in the iOS calendar.
using Google's API Objective-C Client
- (void)addAnEvent {
// Make a new event, and show it to the user to edit
GTLCalendarEvent *newEvent = [GTLCalendarEvent object];
newEvent.summary = @"Sample Added Event";
newEvent.descriptionProperty = @"Description of sample added event";
// We'll set the start time to now, and the end time to an hour from now,
// with a reminder 10 minutes before
NSDate *anHourFromNow = [NSDate dateWithTimeIntervalSinceNow:60*60];
GTLDateTime *startDateTime = [GTLDateTime dateTimeWithDate:[NSDate date]
timeZone:[NSTimeZone systemTimeZone]];
GTLDateTime *endDateTime = [GTLDateTime dateTimeWithDate:anHourFromNow
timeZone:[NSTimeZone systemTimeZone]];
newEvent.start = [GTLCalendarEventDateTime object];
newEvent.start.dateTime = startDateTime;
newEvent.end = [GTLCalendarEventDateTime object];
newEvent.end.dateTime = endDateTime;
GTLCalendarEventReminder *reminder = [GTLCalendarEventReminder object];
reminder.minutes = [NSNumber numberWithInteger:10];
reminder.method = @"email";
newEvent.reminders = [GTLCalendarEventReminders object];
newEvent.reminders.overrides = [NSArray arrayWithObject:reminder];
newEvent.reminders.useDefault = [NSNumber numberWithBool:NO];
// Display the event edit dialog
EditEventWindowController *controller = [[[EditEventWindowController alloc] init] autorelease];
[controller runModalForWindow:[self window]
event:newEvent
completionHandler:^(NSInteger returnCode, GTLCalendarEvent *event) {
// Callback
if (returnCode == NSOKButton) {
[self addEvent:event];
}
}];
}

- 8,463
- 3
- 31
- 21
Update for swift 4 for Dashrath answer
import UIKit
import EventKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let eventStore = EKEventStore()
eventStore.requestAccess( to: EKEntityType.event, completion:{(granted, error) in
if (granted) && (error == nil) {
let event = EKEvent(eventStore: eventStore)
event.title = "My Event"
event.startDate = Date(timeIntervalSinceNow: TimeInterval())
event.endDate = Date(timeIntervalSinceNow: TimeInterval())
event.notes = "Yeah!!!"
event.calendar = eventStore.defaultCalendarForNewEvents
var event_id = ""
do{
try eventStore.save(event, span: .thisEvent)
event_id = event.eventIdentifier
}
catch let error as NSError {
print("json error: \(error.localizedDescription)")
}
if(event_id != ""){
print("event added !")
}
}
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

- 2,129
- 21
- 20
Working code in Swift-4.2
import UIKit
import EventKit
import EventKitUI
class yourViewController: UIViewController{
let eventStore = EKEventStore()
func addEventToCalendar() {
eventStore.requestAccess( to: EKEntityType.event, completion:{(granted, error) in
DispatchQueue.main.async {
if (granted) && (error == nil) {
let event = EKEvent(eventStore: self.eventStore)
event.title = self.headerDescription
event.startDate = self.parse(self.requestDetails.value(forKey: "session_time") as? String ?? "")
event.endDate = self.parse(self.requestDetails.value(forKey: "session_end_time") as? String ?? "")
let eventController = EKEventEditViewController()
eventController.event = event
eventController.eventStore = self.eventStore
eventController.editViewDelegate = self
self.present(eventController, animated: true, completion: nil)
}
}
})
}
}
Now we will get the event screen and here you can also modify your settings:
Now add delegate method to handle Cancel and add the event button action of event screen:
extension viewController: EKEventEditViewDelegate {
func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
controller.dismiss(animated: true, completion: nil)
}
}
Note: Don't forget to add NSCalendarsUsageDescription key into info plist.

- 24,880
- 6
- 40
- 67
Remember to set the endDate to the created event, it is mandatory.
Otherwise it will fail (almost silently) with this error:
"Error Domain=EKErrorDomain Code=3 "No end date has been set." UserInfo={NSLocalizedDescription=No end date has been set.}"
The complete working code for me is:
EKEventStore *store = [EKEventStore new];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent *calendarEvent = [EKEvent eventWithEventStore:store];
calendarEvent.title = [NSString stringWithFormat:@"CEmprendedor: %@", _event.name];
calendarEvent.startDate = _event.date;
// 5 hours of duration, we must add the duration of the event to the API
NSDate *endDate = [_event.date dateByAddingTimeInterval:60*60*5];
calendarEvent.endDate = endDate;
calendarEvent.calendar = [store defaultCalendarForNewEvents];
NSError *err = nil;
[store saveEvent:calendarEvent span:EKSpanThisEvent commit:YES error:&err];
self.savedEventId = calendarEvent.eventIdentifier; //saving the calendar event id to possibly deleted them
}];

- 1,135
- 14
- 34
-
1And also remember that end date must be equal or bigger than the start date. Otherwise, you will get another error. – moody Oct 26 '17 at 12:49
Simple.... use tapku library.... you can google that word and use it... its open source... enjoy..... no need of bugging with those codes....

- 613
- 5
- 21
-
3https://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/EventKitProgGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009765 – Rajesh_Bangalore Aug 28 '12 at 06:27
-
-
All i know is that Tapku library is a calendar component control which has an option called Data source. So its upto ur logic to write the where that source you are fetching from... Happy Coding :) – Rajesh_Bangalore Feb 05 '13 at 05:53
The Google idea is a nice one, but has problems.
I can successfully open a Google calendar event screen - but only on the main desktop version, and it doesn't display properly on iPhone Safari. The Google mobile calendar, which does display properly on Safari, doesn't seem to work with the API to add events.
For the moment, I can't see a good way out of this one.

- 1,294
- 13
- 15