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.
Published: Aug. 30, 2020 Sponsored See booksIn 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 sourceType
s 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