I am using Swift 4.1. And I want to write a function which will collect all events from all calendars in Calendar app of iOS. Thanks to this answer on stackoverflow: How to get all Events out of a Calendar (Swift) I was able to write my own class
and call it Cale
. Please, look at this:
import UIKit
import EventKit
class Cale {
private func createDate(year: Int) -> Date {
var components = DateComponents()
components.year = year
components.timeZone = TimeZone(secondsFromGMT: 0)
return Calendar.current.date(from: components)!
}
private let eventStore = EKEventStore()
private func get() {
let calendars = eventStore.calendars(for: .event)
for calendar in calendars {
// This checking will remove Birthdays and Hollidays callendars
guard calendar.allowsContentModifications else {
continue
}
let start = createDate(year: 2016)
let end = createDate(year: 2025)
print("start: \(start)")
print(" end: \(end)")
let predicate = eventStore.predicateForEvents(withStart: start, end: end, calendars: [calendar])
print("predicate: \(predicate)")
let events = eventStore.events(matching: predicate)
for event in events {
print(" title: \(event.title!)")
print("startDate: \(event.startDate!)")
print(" endDate: \(event.endDate!)")
}
}
}
func checkStatusAndGetAllEvents() {
let currentStatus = EKEventStore.authorizationStatus(for: EKEntityType.event)
switch currentStatus {
case .authorized:
//print("authorized")
self.get()
case .notDetermined:
//print("notDetermined")
eventStore.requestAccess(to: .event) { accessGranted, error in
if accessGranted {
self.get()
} else {
print("Change Settings to Allow Access")
}
}
case .restricted:
print("restricted")
case .denied:
print("denied")
}
}
}
Quite simple class, you can use it, it is working but with one exception.
The main function there is get()
In this function I am creating predicate based on two dates: start and end. As you can see start date is:
2016-01-01 00:00:00 +0000
and end date is:
2025-01-01 00:00:00 +0000
But if we run the program we will see that predicate will be like this:
CADEventPredicate start:01/01/2016, 03:00; end:01/01/2020, 03:00; cals:( 2 )
Only from 2016 to 2020, 4 years! I have tested it on different dates, but I could get predicate with 4 years interval maximum. It means, it will not give me all events! So question is: How to get all events from calendar? If it possible, without using dates!
Thank you for any future help or advice!
In case anyone is still wondering, Apple limited this to four years intentionally.
From predicateForEvents(withStart:end:calendars:):
For performance reasons, this method matches only those events within a four year time span. If the date range between startDate and endDate is greater than four years, it is shortened to the first four years.
If you want a range longer than that, I guess you'll have to wrap this in your own function to split it into four year chunks.