To achieve #1 either a background task to periodically check the calendar for new/updated events, or ability to programmatically subscribe to some sort of an event bus any calendar updates (new events, event changes)
You can do following.
First of all to check new/updated calendar event we don't need to run any background task.
We can get the update for calendar events using .EKEventStoreChanged
notification as followed in viewWillAppear
method.
NotificationCenter.default.addObserver(self, selector: #selector(eventStoreChanged:), name: .EKEventStoreChanged, object: eventStore)
Handle calendar event changes (new / updated) EKEventStore
changes as given below.
func eventStoreChanged(_ notification: Notification) {
let ekEventStore: EKEventStore? = notification.object
let now = Date()
let offsetComponents = DateComponents()
offsetComponents.day = 0
offsetComponents.month = 4
offsetComponents.year = 0
let endDate: Date? = Calendar.current.date(byAddingComponents: offsetComponents, to: now, options: [])
let ekEventStoreChangedObjectIDArray: [Any]? = (notification.userInfo?["EKEventStoreChangedObjectIDsUserInfoKey"] as? [Any])
let predicate: NSPredicate? = ekEventStore?.predicateForEvents(withStartDate: now, endDate: endDate, calendars: nil)
// Loop through all events in range
ekEventStore?.enumerateEvents(matchingPredicate: predicate, usingBlock: {(_ ekEvent: EKEvent, _ stop: Bool) -> Void in
// Check this event against each ekObjectID in notification
(ekEventStoreChangedObjectIDArray as NSArray).enumerateObjects(usingBlock: {(_ ekEventStoreChangedObjectID: String, _ idx: Int, _ stop: Bool) -> Void in
let ekObjectID: NSObject? = (ekEvent as? NSManagedObject)?.objectID
if ekEventStoreChangedObjectID.isEqual(ekObjectID) {
// EKEvent object is the object which is changed.
stop = true
}
})
})
}
So whenever there are any event changes (add/update/delete) we can get updates.
Additionally, when you create any event you get eventIdentifier
from EKEvent
object.
let eventStore : EKEventStore = EKEventStore()
eventStore.requestAccess(to: .event) { (granted, error) in
if (granted) && (error == nil) {
print("granted \(granted)")
print("error \(error)")
let event:EKEvent = EKEvent(eventStore: eventStore)
event.title = "Event"
event.startDate = Date()
event.endDate = Date()
event.calendar = eventStore.defaultCalendarForNewEvents
do {
try eventStore.save(event, span: .thisEvent)
} catch let error as NSError {
print("failed to save event with error : \(error)")
}
print("Saved Event id : \(event.eventIdentifier)")
}
else{
print("failed to save event with error : \(error) or access not granted")
}
}
And get event using following method.
let event:EKEvent = eventStore?.event(withIdentifier: eventIdentifier)
Please let me know if you need any more clarification.