Quantcast
Channel: Andrew Bancroft
Viewing all articles
Browse latest Browse all 57

Creating Calendar Events with Event Kit and Swift

$
0
0

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:

Create Events Demo

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:

class AddEventViewController: UIViewController {

    var calendar: EKCalendar! // Intended to be set in parent controller's prepareForSegue event

    @IBOutlet weak var eventNameTextField: UITextField!
    @IBOutlet weak var eventStartDatePicker: UIDatePicker!
    @IBOutlet weak var eventEndDatePicker: UIDatePicker!

    // ...

    @IBAction func addEventButtonTapped(sender: UIBarButtonItem) {
        // Create an Event Store instance
        let eventStore = EKEventStore();
        
        // Use Event Store to create a new calendar instance
        if let calendarForEvent = eventStore.calendarWithIdentifier(self.calendar.calendarIdentifier)
        {
            let newEvent = EKEvent(eventStore: eventStore)
            
            newEvent.calendar = calendarForEvent
            newEvent.title = self.eventNameTextField.text ?? "Some Event Name"
            newEvent.startDate = self.eventStartDatePicker.date
            newEvent.endDate = self.eventEndDatePicker.date
            
            // Save the calendar using the Event Store instance
            
            do {
                try eventStore.saveEvent(newEvent, span: .ThisEvent, commit: true)
                delegate?.eventDidAdd()
                
                self.dismissViewControllerAnimated(true, completion: nil)
            } catch {
                let alert = UIAlertController(title: "Event could not save", message: (error as NSError).localizedDescription, preferredStyle: .Alert)
                let OKAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
                alert.addAction(OKAction)
                
                self.presentViewController(alert, animated: true, completion: nil)
            }
        }
     }

     // ...
}

Code Walkthrough

The general outline of the code is this:

  • Create an instance of EKEventStore – this will let you create EKEvents and save them.

let newEvent = EKEvent(eventStore: eventStore)

  • Pull an EKCalendar instance from the Event Store – this will let you associate an event with a calendar.

if let calendarForEvent = eventStore.calendarWithIdentifier(self.calendar.calendarIdentifier) { 
// ... 
}

  • Create a new EKEvent instance and set its properties.

let newEvent = EKEvent(eventStore: eventStore)
            
newEvent.calendar = calendarForEvent
newEvent.title = self.eventNameTextField.text ?? "Some Event Name"
newEvent.startDate = self.eventStartDatePicker.date
newEvent.endDate = self.eventEndDatePicker.date

  • Attempt to save the event with the EKEventStore instance that was created first.

do {
    try eventStore.saveEvent(newEvent, span: .ThisEvent, commit: true)
    delegate?.eventDidAdd()
    
    self.dismissViewControllerAnimated(true, completion: nil)
} catch {
    let alert = UIAlertController(title: "Event could not save", message: (error as NSError).localizedDescription, preferredStyle: .Alert)
    let OKAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
    alert.addAction(OKAction)
    
    self.presentViewController(alert, animated: true, completion: nil)
}

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”:

Save Event Sig Kill Error

Save Event Bad Access Error

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:

if let calendarForEvent = eventStore.calendarWithIdentifier((self.calendar.calendarIdentifier))
{
    let newEvent = EKEvent(eventStore: eventStore)
    
    newEvent.calendar = calendarForEvent
    
    // ...
}

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.

The post Creating Calendar Events with Event Kit and Swift appeared first on Andrew Bancroft.


Viewing all articles
Browse latest Browse all 57

Trending Articles