Listing Calendar Events with Event Kit and Swift

This is the continuation of a series of articles I’ve writing for Swift developers working with Event Kit.

Supposing that after asking the user for permission to use their calendars, and even allowing users to create new calendars from within your iOS app, one possible next step could be to list out all of the events for a calendar that they tap on.

Demo

Here’s what we’re going for by the end of this:

List Events Demo

In this walk-through, I’ll explore the Event Kit API that allows us to query the user’s device to find and list out events for a calendar that match a date range.

Example project

I’ve got an example project up on GitHub that contains all the code necessary to list out events for a calendar inside of a table view. You can download that project here:

Querying for events

The primary thing you’ll need to do in order to display a list of events from a calendar is to query the event store for events matching a properly configured NSPredicate.

Here’s a snippet of code, followed by an analysis of what’s going on:

 1class EventsViewController: UIViewController, UITableViewDataSource {
 2    var calendar: EKCalendar! // Passed in from previous view controller
 3    var events: [EKEvent]?
 4
 5    // ...
 6
 7    func loadEvents() {
 8        // Create a date formatter instance to use for converting a string to a date
 9        let dateFormatter = NSDateFormatter()
10        dateFormatter.dateFormat = "yyyy-MM-dd"
11        
12        // Create start and end date NSDate instances to build a predicate for which events to select
13        let startDate = dateFormatter.dateFromString("2016-01-01")
14        let endDate = dateFormatter.dateFromString("2016-12-31")
15        
16        if let startDate = startDate, endDate = endDate {
17            let eventStore = EKEventStore()
18            
19            // Use an event store instance to create and properly configure an NSPredicate
20            let eventsPredicate = eventStore.predicateForEventsWithStartDate(startDate, endDate: endDate, calendars: [calendar])
21            
22            // Use the configured NSPredicate to find and return events in the store that match
23            self.events = eventStore.eventsMatchingPredicate(eventsPredicate).sort(){
24                (e1: EKEvent, e2: EKEvent) -> Bool in
25                return e1.startDate.compare(e2.startDate) == NSComparisonResult.OrderedAscending
26            }
27        }
28    }
29    // ...
30}

Context: View controller

The context of the above snippet is a view controller. Inside the view controller class, there’s a calendar instance that is presumably set in the previous view controller’s prepareForSegue method. There’s also an optional array of EKEvent instances that acts as the data source for a table view, and a function called loadEvents in this view controller.

Configure start and end dates

The first few lines of code within the loadEvents function are to facilitate configuring a start and end date to use for querying the event store.

Use the event store to generate NSPredicate

To actually query the store, you need to create an NSPredicate instance. However, rather than calling NSPredicate's initializer, you will use an EKEventStore instance to generate a predicate. Apparently there’s some under-the-hood work that goes on to get a properly configured NSPredicate instance to use in your query.

So assuming you’ve got a valid start date, end date (both NSDate instances), and one or more calendars to search for events within, you’ll use the event store’s predicateForEventsWithStartDate(_: endDate: calendars:) method to get an NSPredicate instance.

Query the event store with generated NSPredicate

The last step is to call eventsMatchingPredicate(_:) on the event store, and use the predicate you just generated. You can optionally sort them, as I’ve done in the snippet.

Wrapping up

That’s the meat of querying the event store for a list of events. To learn how display them in a table view, I would recommend going ahead and grabbing the example project that I’ve provided. I’ve also got a couple of guides on working with table views if you need assistance with that part:

comments powered by Disqus