Beginner’s Guide to Event Kit in Swift – Requesting Permission

Updated on October 26, 2016 – Swift 3.0

EventKit supplies a set of courses for accessing and manipulating a consumer’s calendar occasions and reminders. Within the tutorial that follows, my objective is to stroll you thru the first steps of establishing an app that utilizes EventKit. I’ll show how to request permission to the consumer’s calendar and show a couple of examples for a way to deal with the consumer’s response (for once they grant access, or deny it).

Word: Code in the primary article under is written in Swift, but code examples for Swift 2.three are discovered in the example undertaking.

Instance state of affairs

Let’s begin by proposing a primary state of affairs to serve as this tutorial’s example.

Suppose that we’re building an app that, for now, has a single View Controller. We’d like this View Controller to show an inventory of calendars if the consumer grants us permission to achieve this. In the event that they deny permission, we’d like to present a message to them that indicates that our app can’t perform without this permission, and we’ll permit them to click a button to grant us permission in the Settings of their gadget.

I’ve created such an app for instance – bounce over to GitHub to seize the code and discover. Learn on for an evidence of a number of the finer points of the setup and code.

Storyboard setup

One of many first belongings you’ll cope with in EventKit is the need to set yourself up with a UI to deal with the totally different responses that the consumer may give you on that first software launch once you ask, “Can we access your calendar?”. We’ll get to the particulars of how request that permission shortly. But first, let’s dissect how we’d organize a Storyboard with some views that do the best factor for a given response to that permission prompt.

The consumer can either grant permission, or deny permission to work together with their calendar or reminders. We’d like to be ready for either state of affairs.

Tableview for the calendar listing for when entry is granted

I’m feeling optimistic in the present day, so let’s begin with the case the place the consumer grants us permission to their calendar from the get-go.

When the consumer grants us permission, we’d like to listing out their calendars inside a table view. We’ll worry with establishing the info supply later in the tutorial. For now, we’ll drag over a desk view from the Utilities pane.

To get the desk view to fill the entire display, I do a couple of things. Often, whenever you drag one out from the Utilities pane, the desk view will fill the entire scene in the Storyboard. From that format, I drag the highest edge down till it “snaps” to the road where I’d anticipate the bottom of the status bar to be positioned. Then I set the following constraints:

  • Middle X
  • Middle Y
  • Equal width to Superview
  • Prime area to Prime Format Guide for peak.

I’ve created a short screencast on establishing a desk view when you’d like an entire walkthrough:

Here’s a detailed view of the constraints, along with a visible of what the Storyboard Scene seems to be like with the table view put in:

Table view in Storyboard

As a ultimate word, I’ve set the hidden property of the desk view to true in the Storyboard. I’ll toggle the table’s visibility based mostly on the consumer’s granting or denying of the calendar access later, but I assumed it was value mentioning that the initial state of my table view in the instance is hidden.

“Need permission” view for when access is denied

There will probably be occasions when a consumer denies access to the calendar earlier than realizing that doing so primarily stops all of the functionality offered by your app. In case your whole app, and even just a portion of it requires access to perform, you want a means to inform the consumer of this, and provide them a means to navigate to settings and grant access manually if potential.

The best way I did this in the pattern undertaking was to manage a brand new View onto the Storyboard Scene which accommodates a label with some directions, and a button that takes the consumer to the Settings page for our app once they faucet on it.

As soon as once more, some constraints are concerned in getting things to seem appropriately at run-time. I gained’t go into the small print of this right here, since it’s probably that each implementation of this might be barely totally different.

One thing I’ll level out though, is that the View’s alpha has been set to 0 in order that I can carry out a nice fade in transition if the consumer denies entry. Here’s a take a look at the Scene with the invisible “NeedPermissionsView” put in:

Need permission view

The position of the Event Retailer

On the coronary heart of EventKit is the EKEventStore. EKEventStore is the central “thing”. Creating an occasion of EKEventStore offers builders with an API for performing numerous learn/write operations on the consumer’s calendars and reminder lists.

A View Controller that interacts with the calendar should maintain a reference to an EKEventStore occasion. It’s straightforward to create one – right here’s an instance:

1class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
three let eventStore = EKEventStore()
5 // …

Checking for calendar authorization

Once we have now a reference to an EKEventStore instance, we will use it to do things like examine whether or not the consumer has granted us permission to use their calendar. From there, we will make selections about whether or not or not we’d like to request permission, and subsequently work out which view to show (the desk view or the need permission view).

Where we examine for calendar authorization is essential. My suggestion is to verify each time the view seems (ie, in viewWillAppear(), as a result of it’s utterly attainable that the consumer might grant entry at first, change to settings, and deny access. Our app would wish to respond appropriately.

In the example challenge provided with this text, I’ve created a perform named checkCalendarAuthorizationStatus(). Here a peek at what it does:

1class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
three // …
5 override func viewWillAppear(animated: Bool)
6 checkCalendarAuthorizationStatus()
9 func checkCalendarAuthorizationStatus()
10 let standing = EKEventStore.authorizationStatus(for: EKEntityType.occasion)
12 change (status)
13 case EKAuthorizationStatus.notDetermined:
14 // This occurs on first-run
15 requestAccessToCalendar()
16 case EKAuthorizationStatus.approved:
17 // Issues are in line with being able to present the calendars in the table view
18 loadCalendars()
19 refreshTableView()
20 case EKAuthorizationStatus.restricted, EKAuthorizationStatus.denied:
21 // We’d like to help them give us permission
22 needPermissionView.fadeIn()
26 // …

The important thing perform here is EKEventStore’s authorizationStatus(for:) perform. Passing in EKEntityType.occasion is what corresponds to the consumer’s calendar. If we needed to verify for access to their reminders, we’d use EKEntityTypeReminder.

The potential EKAuthorizationStatus enumeration values are merely switched over – the logic to be carried out is encapsulated in separate features for ease of readability.

Let’s step by means of every of these features one after the other…

Replace Information.plist for iOS 10 help

Apple now requires us to have a key/value pair in Information.plist that gives a description to the consumer as to why our apps want entry to their calendar.

To set this worth, open your Information.plist file, and add a brand new key for “Privacy – Calendars Usage Description”:
Info.plist Calendar Usage Description

The worth that you simply present for this plist key finally ends up being displayed in the alert that’s displayed whenever you request entry.

Requesting access to calendars

Because the title of this tutorial suggests, all things start right here. Every time our software masses and we name authorizationStatus(for:), the standing that shall be returned is notDetermined. It’s at this point that we’d like to request entry to the calendar.

To do so, let’s dissect the requestAccessToCalendar perform:

1class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
3 // …
5 func requestAccessToCalendar()
6 eventStore.requestAccess(to: EKEntityType.event, completion:
7 (accessGranted: Bool, error: Error?) in
9 if accessGranted == true
10 DispatchQueue.principal.async(execute:
11 self.loadCalendars()
12 self.refreshTableView()
13 )
14 else
15 DispatchQueue.major.async(execute:
16 self.needPermissionView.fadeIn()
17 )
19 )
22 // …

Our EKEventStore instance offers a perform referred to as requestAccess(to:). As soon as again, passing in EKEntityType.occasion is what alerts that we’re requesting entry to the calendar. The rest of the fascinating elements are discovered in the completion closure that we offer.

There are three principal issues to notice with this portion of the implementation:

  1. The 2 parameters which might be passed in to the closure is a Bool indicating entry was granted (true) or denied (false). The second is an NSError.
  2. We’d like to name dispatch_async() and indicate that we would like to leap back over to the primary queue to execute our UI refreshes.
  3. self.needPermissionView.fadeIn() makes use of a UIView extension from my submit, Fade In / Out Animations as Class Extensions in Swift.
Access granted! Load calendars and refresh table view

When entry is granted, we will call the eventStore occasion’s calendarsForEntityType perform and cross it EKEntityType.event to seize an array of the consumer’s calendars to show in our table view. Right here’s a look:

1class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
three // …
5 var calendars: [EKCalendar]?
7 // …
9 func loadCalendars()
10 self.calendars = eventStore.calendars(for: EKEntityType.occasion)
13 func refreshTableView()
14 calendarsTableView.isHidden = false
15 calendarsTableView.reloadData()
18 // …
Entry denied – Present wants permission view

When access is denied, we’d like to unveil the “Needs Permission View” we created in our Storyboard Scene.

Recall that in that view, there’s a button to direct the consumer to the Settings web page for our app in order that they will easily grant entry to the calendar from there. That button is wired up to an IBAction. Here’s an example implementation of that IBAction:

1class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
3 // …
5 @IBAction func goToSettingsButtonTapped(_ sender: UIButton)
6 let openSettingsUrl = URL(string: UIApplicationOpenSettingsURLString)
7 UIApplication.shared.openURL(openSettingsUrl!)
10 // …

Wrapping up

That just about completes the setup process for working with Event Kit! The remaining instances for the checkCalendarAuthorizationStatus() perform simply re-use the features I just dissected when exploring the requesting permission process.

I encourage you to head over to GitHub and dive into the code for yourself as you get started with using Event Kit in your app!