3. Requesting Permission to Access Calendars
Init EKEventStore:
eventStore = EKEventStore()
Check authorization status:
let status:EKAuthorizationStatus = EKEventStore.authorizationStatusForEntityType(EKEntityTypeEvent)
switch (status) {
case .Authorized: accessGrantedForCalendar()
break
case .NotDetermined: requestCalendarAccess()
break
case .Denied, .Restricted:
break
}
Request Calendar access:
eventStore?.requestAccessToEntityType(EKEntityTypeEvent, completion: {
[weak self] (granted:Bool, error:NSError!) -> Void in
dispatch_async(dispatch_get_main_queue()) {
self!.accessGrantedForCalendar()
}
})
4. func fetchCallendarGroups(eventStore:EKEventStore) {
for source in eventStore.sources() as [EKSource] {
println("Group: title = (source.title)" +
" type = (source.sourceType.value)")
}
}
/* Log
Group: title = Default type = 0
Group: title = Other type = 5
Group: title = Gmail type = 2
Group: title = CalDAV type = 2
Group: title = iCloud type = 2
*/
Event. Fetch Calendar Groups
5. func fetchAllCallendars() {
Event. Fetch All Calendars
let calendars = eventStore.calendarsForEntityType(EKEntityTypeEvent) as [EKCalendar]
for calendar in calendars {
println("Calendar: title = (calendar.title)" +
" type = (calendar.type.value)" +
" allows modifications = (calendar.allowsContentModifications)")
}
}
/* Log
Calendar: title = Work type = 1 allows modifications = true
Calendar: title = Home type = 1 allows modifications = true
Calendar: title = Birthdays type = 4 allows modifications = false
Calendar: title = a.voityuk@gmail.com type = 1 allows modifications = true
Calendar: title = Calendar type = 1 allows modifications = false
*/
6. Event. Fetch Events Using Predicates
func fetchEvents(calendar: EKCalendar) {
/* The event starts from today, right now */
let startDate = NSDate()
/* The end date will be 7 day from now */
let endDate = startDate.dateByAddingTimeInterval(24 * 60 * 60 * 7)
/* Create the predicate that we can later pass to the event store in order to fetch the events */
let searchPredicate = eventStore.predicateForEventsWithStartDate(startDate, endDate: endDate, calendars: nil)
/* Fetch all the events that fall between the starting and the ending dates */
let events = eventStore.eventsMatchingPredicate(searchPredicate) as [EKEvent]
for event in events {
println("Event: title = (event.title)")
}
}
/* Log
Event: title = Alexander Voityuk’s 28. Birthday
Event: title = Maxim Matyash’s 30. Birthday
*/
7. func createEventWithTitle(title: String, startDate: NSDate, endDate: NSDate, inCalendar: EKCalendar, inEventStore: EKEventStore) -> Bool {
/* Create an event */
var event = EKEvent(eventStore: inEventStore)
event.calendar = inCalendar
/* Set the properties of the event such as its title, start date/time, end date/time, etc. */
event.title = title
event.startDate = startDate
event.endDate = endDate
/* Finally, save the event into the calendar */
var error:NSError?
let result = inEventStore.saveEvent(event,
span: EKSpanThisEvent,
error: &error)
return result
}
Event. Create Event
8. func removeEvent(event: EKEvent, store: EKEventStore, calendar: EKCalendar) -> Bool{
var result = false
var error:NSError?
/* remove the event from the calendar */
if store.removeEvent(event,
span: EKSpanThisEvent,
commit: true,
error: &error) {
result = true
} else if let theError = error {
println("Failed to remove (event) with error = (theError)")
}
return result
}
Event. Remove Event
9. func addAlarmToCalendarWithStore(title: String, startDate: NSDate, endDate: NSDate, store: EKEventStore, calendar: EKCalendar) {
/* Assign the required properties, especially the target calendar */
let eventWithAlarm = EKEvent(eventStore: store)
eventWithAlarm.title = title
eventWithAlarm.calendar = calendar
eventWithAlarm.startDate = startDate
eventWithAlarm.endDate = endDate
/* The alarm goes off 2 seconds before the event happens */
let alarm = EKAlarm(relativeOffset: -2.0)
eventWithAlarm.addAlarm(alarm)
var error:NSError?
if store.saveEvent(eventWithAlarm, span: EKSpanThisEvent, error: &error) {
println("Saved an event that fires 60 seconds from now.")
} else if let theError = error {
println("Failed to save the event. Error = (theError)")
}
}
Event. Add Alarm
10. func addRecurringRuleToEvent(event: EKEvent) {
/* The end date of the recurring rule is one year from now */
let oneYear:NSTimeInterval = 365 * 24 * 60 * 60;
let oneYearFromNow = startDate.dateByAddingTimeInterval(oneYear)
/* Create an Event Kit date from this date */
let recurringEnd = EKRecurrenceEnd.recurrenceEndWithEndDate(oneYearFromNow) as EKRecurrenceEnd
/* And the recurring rule. This event happens every
month (EKRecurrenceFrequencyMonthly), once a month (interval:1)
and the recurring rule ends a year from now (end:RecurringEnd) */
let recurringRule = EKRecurrenceRule(
recurrenceWithFrequency: EKRecurrenceFrequencyMonthly,
interval: 1,
end: recurringEnd)
/* Set the recurring rule for the event */
event.recurrenceRules = [recurringRule]
}
Event. Add Recurring Rule
11. func fetchAllCallendars() {
Reminder. Fetch All Calendars
let calendars = eventStore.calendarsForEntityType(EKEntityTypeReminder) as [EKCalendar]
for calendar in calendars {
println("Calendar: title = (calendar.title)" +
" type = (calendar.type.value)" +
" allows modifications = (calendar.allowsContentModifications)")
}
}
/* Log
Calendar: title = Reminders type = 1 allows modifications = true
*/
12. Reminder. Fetch Reminders Using Predicates
func fetchReminders(calendar: EKCalendar) -> NSMutableArray {
/* The event starts from today, right now */
let startDate = NSDate()
/* The end date will 7day from now */
let endDate = startDate.dateByAddingTimeInterval(24 * 60 * 60 * 7)
/* Create the predicate that we can later pass to the event store in order to fetch the events */
let searchPredicate = eventStore.predicateForIncompleteRemindersWithDueDateStarting(startDate, ending: endDate, calendars: nil)
/* Fetch all the reminder that fall between the starting and the ending dates */
eventStore.fetchRemindersMatchingPredicate(searchPredicate, completion: {
(reminders) -> Void in
for reminder in reminders {
println("Event: title = (reminder.title)")
}
})
}
/* Log
Reminder: title = My Reminder 1
Reminder: title = My Reminder 2
*/
13. func createReminderWithTitle(title: String, inCalendar: EKCalendar, inEventStore: EKEventStore, notes: String) -> Bool {
/* Create an reminder */
var reminder = EKReminder(eventStore: inEventStore)
reminder.calendar = inCalendar
/* Set the properties of the event such as its title, notes. */
reminder.title = title
reminder.notes = notes
/* Finally, save the reminder into the calendar */
var error:NSError?
let result = inEventStore.saveReminder(reminder,
commit: true,
error: &error)
if result == false {
if let theError = error{
println("An error occurred (theError)")
}
}
return result
}
Reminder. Create Reminder
14. func removeReminder(reminder: EKReminder, store: EKEventStore, calendar: EKCalendar) -> Bool{
var result = false
var error:NSError?
/* remove the reminder from the calendar */
if store.removeReminder(reminder,
commit: true,
error: &error) {
result = true
} else if let theError = error{
println("Failed to remove (reminder) with error = (theError)")
}
return result
}
Reminder. Remove Reminder
15. /* Add observer */
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "eventStoreDidChanged:",
name: EKEventStoreChangedNotification,
object: nil)
func eventStoreDidChanged(notification:NSNotification) {
// TODO
}
Observing External Changes
to the Calendar Database
16. Add delegate EKEventViewDelegate to current ViewController
func displayExistingEvent(event : EKEvent, store : EKEventStore) {
let controller:EKEventViewController = EKEventViewController()
controller.event = event;
controller.allowsEditing = true;
self.presentViewController(UINavigationController(rootViewController: controller), animated: true, completion: nil)
}
// MARK: - EKEventViewDelegate
func eventViewController(controller: EKEventViewController!, didCompleteWithAction action: EKEventViewAction) {
self.dismissViewControllerAnimated(true, completion: {
() -> Void in
// TODO
})
}
Interfaces for Events. Displaying Event Data
17. Add delegate EKEventEditViewDelegate to current ViewController
func editExistingEvent(event : EKEvent, store : EKEventStore) {
let controller:EKEventEditViewController = EKEventEditViewController()
controller.event = event
controller.eventStore = store
controller.editViewDelegate = self
self.presentViewController(controller, animated: true, completion: nil)
}
// MARK: - EKEventEditViewDelegate
func eventEditViewController(controller: EKEventEditViewController!, didCompleteWithAction action: EKEventEditViewAction) {
self.dismissViewControllerAnimated(true, completion: {
() -> Void in
// TODO
})
}
func eventEditViewControllerDefaultCalendarForNewEvents(controller: EKEventEditViewController!) -> EKCalendar! {
return defaultCalendar
}
Interfaces for Events. Modifying Event Data
18. End
Calendar and Reminders Programming Guide:
https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/EventKitProgGuide/Introduction/Introduction.html
Apple Sample Project “SimpleEKDemo”:
https://developer.apple.com/library/ios/samplecode/SimpleEKDemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010160