How to save event into user's calendar

In this post we will use the EventKit framework to save event to default calendar.

Published: June 20, 2020
See books

If your app deals with some kind of events you can make it easy for the user to save particular events into their calendar. This way they won't have to remember be and can plan accordingly.

Working with calendars in iOS is pretty good thanks to the EventKit framework. In this post we will focus on the minimal example to save an event into user's calendar.

Configure Info.plist

As with other private stuff, the first step is to configure Info.plist and then requesting access.

To save an event you need to add the key NSCalendarsUsageDescription to Info.plist with explanation why you need calendar access.

Import and event store

Once that is done we can move to Swift code and start by importing EventKit and also creating an instance of EKEventStore which is used to manage events.

import EventKit

let eventStore = EKEventStore()

Requesting access

Once eventStore is created, we can move to requesting access to the calendar.

func requestAccess() {
    eventStore.requestAccess(to: .event) { (granted, error) in
        if granted {
            // save event
        }
    }
}

I would recommend checking access often because user can change their mind and remove access in Settings.

If access was granted we can save the event. In case of touching UI somehow we would need DispatchQueue.main.async to make sure we are on the main thread.

The eventStore has property defaultCalendarForNewEvents we can use to get user's default calendar. This is quite sensible default for new events and we don't need to prompt the user to choose calendar.

However in the real app it would be a good idea to have some sort of fallback. At least showing an alert explaining that there is not a default calendar or better using EKCalendarChooser to let user select an alternative. I have a post about it also.

Creating event

Assuming we have a calendar, we can create an event using our eventStore:

guard let calendar = eventStore.defaultCalendarForNewEvents else { return }       
let event = EKEvent(eventStore: eventStore)

Saving an event is done via EKEventStore so we need to associate it.

Next step is to configure the EKEvent with data:

event.title = "This is my test event"
event.startDate = Calendar.current.date(byAdding: .day, value: 1, to: Date())!
event.isAllDay = true
event.endDate = event.startDate

Note that the endDate is required even when you want event for just one day. Without it you will get an error trying to save.

Next we assign the calendar:

event.calendar = calendar

Saving event

And lastly we save the event:

try eventStore.save(event, span: .thisEvent, commit: true)

The span argument is required even though it does not really make sense for non-recurring events. commit means that the event will get saved immediately.

Alternative would be to commit later via dedicated method. This is useful when you are saving multiple events:

try eventStore.save(event, span: .thisEvent)
try eventStore.commit()

And done! If you run the above code, check your calendar for new event 🙂

Comprehensive example

If you are interested in more EventKit you can check my other posts or open-source project showcasing working with different parts of the framework.

Uses: Xcode 12 & Swift 5.3

Bluesky logo

Follow on Bluesky to not miss new posts

Filip Němeček profile photo

WRITTEN BY

Filip Němeček Mastodon

iOS blogger and developer with interest in Python/Django.

iOS blogger and developer with interest in Python/Django.