How to create new calendar using EventKit in Swift

Apart from reminders and events, EventKit framework also gives you the power to create new calendars for users. Learn how.

In the previous posts I already wrote about creating events and reminders using EventKit. Turns out you can create a new calendar too.

The process does not involve much. Basically "just" creating an instance of EKCalendar , configuring it and saving. But there is one big caveat called EKSource.

This is required otherwise the calendar can't be saved. We can use an instance of EKEventStore to query all available sources but figuring which one to use is tricky.

Preparing EKSource

It also depends if you want for your user to pick this source. In this case you should present it as choosing an account which it ultimate represents and you can use title property as user readable identifier. This can be something like "iCloud", "Gmail" and others.

Or you can try picking the best one which I have done for my example EventKit project:

func bestPossibleEKSource() -> EKSource? {
    let `default` = eventStore.defaultCalendarForNewEvents?.source
    let iCloud = eventStore.sources.first(where: { $0.title == "iCloud" }) // this is fragile, user can rename the source
    let local = eventStore.sources.first(where: { $0.sourceType == .local })

    return `default` ?? iCloud ?? local
}

I think for an example this works fine. I first try to get source from the default calendar, if that fails we can try finding one named "iCloud" but user can rename them, and lastly try local.

The available sourceTypes are available in official docs. The calDAV could be promising:

Represents a CalDAV or iCloud source.

As I said. It depends on what you are building. If it is fully featured calendar app then it makes sense to let user pick the source.

Creating calendar

Finally. With EKSource out of the way, let's create a new calendar:

func createNewCalendar(withName name: String) {
    let calendar = EKCalendar(for: .event, eventStore: eventStore)
    calendar.title = name
    calendar.cgColor = UIColor.purple.cgColor

    guard let source = bestPossibleEKSource() else {
        return // source is required, otherwise calendar cannot be saved
    }
    calendar.source = source   
    try! eventStore.saveCalendar(calendar, commit: true)
}

Notice we also configured calendar's color along with the title.

Complete code

The full code is available in the example project on GitHub. You can also check out my other EventKit articles.

Uses: Xcode 12 & Swift 5.3


Follow me on Twitter for latest updates and news