Creating Calendar Events with Event Kit and Swift
Folks have asked more about working with Event Kit and Swift, so the series continues with this guide on how to create calendar events with Event Kit and Swift!
Previous guides in the series include the following:
Demo
Here’s what we’re going for by the end of this:
As with my other guides, I’ve included a working project on GitHub for you to peruse and tinker with:
Code Example
The majority of the work to create an event happens in the example project’s AddEventViewController.swift file, so that’s where I’ll spend my time in this guide. First, let’s put the relevant code before us:
1class AddEventViewController: UIViewController {
2
3 var calendar: EKCalendar! // Intended to be set in parent controller's prepareForSegue event
4
5 @IBOutlet weak var eventNameTextField: UITextField!
6 @IBOutlet weak var eventStartDatePicker: UIDatePicker!
7 @IBOutlet weak var eventEndDatePicker: UIDatePicker!
8
9 // ...
10
11 @IBAction func addEventButtonTapped(sender: UIBarButtonItem) {
12 // Create an Event Store instance
13 let eventStore = EKEventStore();
14
15 // Use Event Store to create a new calendar instance
16 if let calendarForEvent = eventStore.calendarWithIdentifier(self.calendar.calendarIdentifier)
17 {
18 let newEvent = EKEvent(eventStore: eventStore)
19
20 newEvent.calendar = calendarForEvent
21 newEvent.title = self.eventNameTextField.text ?? "Some Event Name"
22 newEvent.startDate = self.eventStartDatePicker.date
23 newEvent.endDate = self.eventEndDatePicker.date
24
25 // Save the calendar using the Event Store instance
26
27 do {
28 try eventStore.saveEvent(newEvent, span: .ThisEvent, commit: true)
29 delegate?.eventDidAdd()
30
31 self.dismissViewControllerAnimated(true, completion: nil)
32 } catch {
33 let alert = UIAlertController(title: "Event could not save", message: (error as NSError).localizedDescription, preferredStyle: .Alert)
34 let OKAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
35 alert.addAction(OKAction)
36
37 self.presentViewController(alert, animated: true, completion: nil)
38 }
39 }
40 }
41
42 // ...
43}
Code Walkthrough
The general outline of the code is this:
- Create an instance of
EKEventStore– this will let you createEKEventsand save them.
1let newEvent = EKEvent(eventStore: eventStore)
- Pull an
EKCalendarinstance from the Event Store – this will let you associate an event with a calendar.
1if let calendarForEvent = eventStore.calendarWithIdentifier(self.calendar.calendarIdentifier) {
2// ...
3}
- Create a new
EKEventinstance and set its properties.
1let newEvent = EKEvent(eventStore: eventStore)
2
3newEvent.calendar = calendarForEvent
4newEvent.title = self.eventNameTextField.text ?? "Some Event Name"
5newEvent.startDate = self.eventStartDatePicker.date
6newEvent.endDate = self.eventEndDatePicker.date
- Attempt to save the event with the
EKEventStoreinstance that was created first.
1do {
2 try eventStore.saveEvent(newEvent, span: .ThisEvent, commit: true)
3 delegate?.eventDidAdd()
4
5 self.dismissViewControllerAnimated(true, completion: nil)
6} catch {
7 let alert = UIAlertController(title: "Event could not save", message: (error as NSError).localizedDescription, preferredStyle: .Alert)
8 let OKAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
9 alert.addAction(OKAction)
10
11 self.presentViewController(alert, animated: true, completion: nil)
12}
Gotchas
As I was working through this example, I was initially running into trouble when associating my newEvent with the calendar that was passed into AddEventViewController from the parent controller’s prepareForSegue method.
It turns out that if you retrieve a calendar from one EKEventStore instance, say, in the previous view controller, and attempt to assign it to an EKEvent that is associated with a different EKEventStore instance, things become really unhappy when it comes time to save the event.
Specifically, you’ll get an error that says “Thread 1: signal SIGKILL” followed by “Thread 1: EXC_BAD_ACCESS”:
The fix for this was easy, once I figured out what was going on: Simply re-retrieve a calendar instance using an appropriate calendarIdentifier from the EKEventStore instance you’re using to save the EKEvent with:
1if let calendarForEvent = eventStore.calendarWithIdentifier((self.calendar.calendarIdentifier))
2{
3 let newEvent = EKEvent(eventStore: eventStore)
4
5 newEvent.calendar = calendarForEvent
6
7 // ...
8}
Wrapping up
My focus in this guide was to demonstrate how to create and save and event to a user’s calendar. I intentionally left out a lot of the navigation aspects and prepareForSegue calls in order to highlight the event creation process itself. Be sure to check out the accompanying Xcode project on GitHub for full details on the flow of the application.


