Eventkit provides a series of classes for getting and manipulating user calendar events and reminders. In the following tutorial, My goal is to lead you out of using Eventkit to build an application. My goal is to lead you to the first step in building an application with Eventkit. I'll show you how to request permission for a user's calendar, and I'll demonstrate several examples of handling user responses when they grant access, or rejected).
Example Scenario
Scene
Let's start with a basic scenario as an example of this tutorial.
Suppose we are building an application that now has a single view controller. With the permission of the user, we want this view controller to display a list of calendars. If the user denies access, we will present a message to the user stating that our application cannot run without access, and we will allow them to set authorization access in their device settings by clicking on a button.
I have created an application like that as an example – jump to GitHub to view and study the code for this example.
Storyboard Setup
Story Panel settings
The first step in your use of Eventkit is to create a user interface for yourself to handle when your first program starts and the user can access your calendar from the program? For a different response, we will soon get the details on how to request this license. But first, let's examine how we can arrange our storyboard with some view of how a given response could do the right thing for a licensed operation.
Users can grant access, or they can deny access to notify their calendars or reminders. We need to be prepared for both situations.
TableView Displays the Calendar list when Access is granted
I'm optimistic today, so let's get started on how users are granted access to their calendars from the start.
When the user grants us access, we want to list a table view of the calendar. In the next tutorial, we'll worry about setting up the data source. Now we're going to drag a table view from the utility bar.
In order to get a table view that fills the entire screen, I've done a few things. Usually, when you drag a table view from the utility bar, it fills the entire scene in the storyboard. In the layout I drag the top edge down to know it "snaps" to the row that I want to be positioned at the bottom of the status bar.
I have created a short screenshot of the Settings table view, and if you want a complete exercise, you can see the following link:
Here are detailed views of these constraints, and the storyboard looks like a visual effect of the table view.
Finally, in the storyboard I have set the hidden property of this table view to true. I switch the visibility of the table after the user allows or denies access to the calendar, but I think it's worth noting that in my case the initial state of the table view is hidden.
Require permission view when Access is denied
But sometimes, users who refuse to grant access to the calendar, aware that doing so will result in essentially stopping all of your application's functionality, if your entire application or just part of the application requires access to functionality, you need a way to inform the user and provide them with a way to jump to the user settings, If possible, let the user manually grant access rights.
My approach in the example project is to organize a new view in the storyboard scene that contains a label that shows the operation description and a button that allows the user to enter the settings interface of our application after a click.
Again, some constraints involve the right display of things at run time. I'm not going to go into this detail here, because it's probably a little different because of each execution.
I will point out the idea of the thing is that the transparency of this view has been set to 0 so that if the user refuses to authorize, I can show a fading effect. Here's a look at the scenario where the hidden "Needpermissionsview" is set:
Role of Event Store
The core of Eventkit is that Ekeventstore.ekeventstore is the center of things. Creates an instance of Ekeventstore that provides developers with an API to perform various read/write operations on the user's calendars and reminders list.
A view controller that interacts with the calendar should have an instance that references Ekeventstore. This is easy to create – here is an example:
1234 |
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { let eventStore = EKEventStore() // ... } |
Check your calendar for authorization
Once we have an instance of referencing Ekeventstore, we can do things like checking whether a user is authorized to access their calendars. Based on this, we can do a decision on whether or not to request permission, and then determine the view to display (table view or require a licensed view).
Where we check calendar authorization is important. My advice is to check every time the view appears (that is, in Viewwillappear ()), because the first time a user grants access, switch settings, and deny access is entirely possible. Our application needs to respond appropriately.
In the example project provided with this article, I ' ve created a function named Checkcalendarauthorizationstatus (). Here's a peek at what it does:
In the example project provided in this article, I have created a function called Checkcalendarauthorizationstatus ().
Next look at its implementation:
Viewcontroller.swift
12345678910111213141516171819202122232425 |
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// ...
override func viewWillAppear(animated: Bool) {
checkCalendarAuthorizationStatus()
}
func checkCalendarAuthorizationStatus() {
let status = EKEventStore.authorizationStatusForEntityType(EKEntityTypeEvent)
switch
(status) {
case
EKAuthorizationStatus.NotDetermined:
// This happens on first-run
requestAccessToCalendar()
case
EKAuthorizationStatus.Authorized:
// Things are in line with being able to show the calendars in the table view
loadCalendars()
refreshTableView()
case
EKAuthorizationStatus.Restricted, EKAuthorizationStatus.Denied:
// We need to help them give us permission
needPermissionView.fadeIn()
default
:
let alert = UIAlertView(title:
"Privacy Warning"
, message:
"You have not granted permission for this app to access your Calendar"
, delegate: nil, cancelButtonTitle:
"OK"
)
alert.show()
}
}
// ...
}
|
The key feature here is Ekeventstore's Authorizationstatusforentitytype implementation. The incoming ekentitytypeevent is used to interact with the user's calendar. If we want to check their alert permissions, We will use the ekentitytypereminder here.
The possible values of the Ekauthorizationstatus are based on the corresponding case in the switch to execute the logical code of the encapsulated, easy-to-read, standalone function.
Let's take a closer look at these features.
Request access to Calendar
As the title says, everything starts here. Whenever our application loads and calls Authorizationstatusforentitytype, it returns the state of notdetermined. At this point we would like to request access to the calendar.
To do this, define the Requestaccesstocalendar function in the following way:
12345678910111213141516171819202122 |
requestAccessToCalendar()
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// …
func requestAccessToCalendar() {
eventStore.requestAccessToEntityType(EKEntityTypeEvent, completion: {
(accessGranted: Bool, error: NSError!)
in
if
accessGranted ==
true
{
// Ensure that UI refreshes happen back on the main thread!
dispatch_async(dispatch_get_main_queue(), {
self.loadCalendars()
self.refreshTableView()
})
}
else
{
// Ensure that UI refreshes happen back on the main thread!
dispatch_async(dispatch_get_main_queue(), {
self.needPermissionView.fadeIn()
})
}
})
}
// …
}
|
Our Ekeventstore instance provides a function called Requestaccesstoentitytype. Again, pass the ekentitytypeevent as the parameter we requested to access the calendar. The rest of the interesting parts can be found in the enclosed closures we provide .
There are three main things to note in the implementation:
Two parameters passed to the closure one is the bool type that is used to indicate whether access rights are granted, and the other is nserror.
We need to call Dispatch_async () and indicate that we are going back to the main queue to perform the refresh UI.
Self.needPermissionView.fadeIn () as an extension of the uiview in my operation, [the extended class of the fade in/out animation of Swift (Fade in/out animations as Class Extensions in Swift)] (https://github.com/andrewcbancroft/EventTracker/tree/ask-for-permission).
Grant Access! Load the calendar and refresh the table view
When allowed to access, we can invoke the Calendarsforentitytype function in the Eventstore instance and pass the ekentitytypeevent to fetch the array of the user's calendar to display in our table view. Here's a look:
1234567891011121314 |
loadCalendars()
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// ...
var
calendars: [EKCalendar]?
// ...
func loadCalendars() {
self.calendars = eventStore.calendarsForEntityType(EKEntityTypeEvent) as? [EKCalendar]
}
func refreshTableView() {
calendarsTableView.hidden =
false
calendarsTableView.reloadData()
}
// ...
}
|
Access Denied – Display requires a licensed view
When access is denied, we need to pop up the "Needs Permission View" created in the storyboard scene.
In this view, the above function is called again, so that a user can jump directly to the settings page of our application so that they can authorize calendar access from there. This button is wired to a ibaction. Here are some examples of implementing ibaction:
123456789 |
goToSettingsButtonTapped()
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// ...
@IBAction func goToSettingsButtonTapped(sender: UIButton) {
let openSettingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
UIApplication.sharedApplication().openURL(openSettingsUrl!)
}
// ...
}
|
Conclusion
This is almost done with the start of the Event Kit! For simple reuse of the rest of the Checkcalendarauthorizationstatus () function, I simply dissected the process of requesting permission.
I encourage you to jump to GitHub and explore the code yourself as you begin using the event kit in your application.
Swift Eventkit Beginner's Guide – Request permission