How to save event into user's calendar

In this post we will use the EventKit framework to save event into user's default calendar.

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.

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.

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()

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.

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

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 🙂

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 11 & Swift 5